/* ******************************************************************************************************* */
/* ******************** Use contentious proposals held at firms with more liquid stock *********************/
/* ******************************************************************************************************* */
data temp; set temp.iss_votes_ret;
  if 0 < abs(margin) <= .20 and issue ne '';

proc sort data = temp nodupkey out = proposals (keep=year mend exchcd shrcd rqdate wficn crsp_cl_grp winvote wt permno meetingdate mgmt_sponsored mgmt_win margin agendaGeneralDesc Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue pwt); 
  by wficn crsp_cl_grp mend permno meetingdate wt itemonagendaid; 

proc sort data = proposals out = unique (keep=wficn crsp_cl_grp mend exchcd shrcd) nodupkey; by wficn crsp_cl_grp mend; 

proc sql;
  create table reg as
  select a.wficn, a.crsp_cl_grp, a.mend, b.permno, b.meetingdate, b.itemonagendaid, b.issForMgmt, b.iss_conform, b.car12d_m, b.car12d_m_win, b.WinVote, b.margin, b.mgmt_win, b.market_value_pr2, b.market_value_adj, b.pwt, b.pwt_adj
  from unique as a, test1 as b
  where a.wficn = b.wficn and a.crsp_cl_grp = b.crsp_cl_grp and 1 <= intck('month', b.meetingdate, a.mend) <= 12; 
quit; * test1 is from 09Tests_fund_level.sas;

proc sql;
  create table reg as 
  select a.*, b.r_illiq2
  from reg as a left join temp.cst_matched as b
  on a.permno = b.permno and intck('day', a.meetingdate, b.meetingdate) = 0;
quit;

proc sort nodupkey; by _all_; run;

proc sort data = reg; by wficn crsp_cl_grp mend; where market_value_adj ne . and r_illiq2 in (0); * bottom tercile in Amihud illiquidity;

proc means data = reg noprint; by wficn crsp_cl_grp mend; 
  where car12d_m ne .; 
  var WinVote;
  output out = count2 (drop=_type_ _freq_) n = num_votes;

proc means data = reg noprint; by wficn crsp_cl_grp mend; 
  var car12d_m_win; weight market_value_adj; 
  output out = win_ret_1 (drop=_type_ _freq_) mean = vote_alpha ;

data measure; merge count2 win_ret_1; by wficn crsp_cl_grp mend; 

proc sort data = temp.fundinfo nodupkey out = fundinfo; by wficn crsp_cl_grp caldt; where mtna ne .; 

proc sql;
  create table measure as
  select a.*, b.caldt, b.crsp_obj_cd2, b.mtna, b.mtna_adj, b.pct_common_eq
  from measure as a left join fundinfo as b
  on a.wficn = b.wficn and a.crsp_cl_grp = b.crsp_cl_grp and 1 <= intck('month', b.caldt, a.mend) <= 6;
quit;

proc sort; by wficn crsp_cl_grp mend caldt; 

data measure; set measure; by wficn crsp_cl_grp mend caldt; 
  if last.mend;
  if (index(crsp_obj_cd2, 'ED') = 1) and mtna >= 5 and num_votes > 10; 

proc sort; by mend;

proc rank data = measure out  = measure groups = 5; by mend;
  var vote_alpha ;
  ranks q_vote_alpha ;
run;

proc means n mean median p1 p99 min max data = proposals;
  var wt; run;

proc sort data = measure; by wficn crsp_cl_grp mend; 

data proposals2; merge proposals measure; by wficn crsp_cl_grp mend;
  if wt ne .;
run;

proc sort data = proposals2 nodupkey; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year wficn crsp_cl_grp; 

proc means data = proposals2 noprint; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year;
  var wt; 
  output out = count3 (drop=_type_ _freq_) sum = mfo n = num_mf;

proc sort; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year;

proc means data = proposals2 noprint; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year; 
  var wt; where q_vote_alpha in (4) and WinVote = 1; 
  output out = win_ret_2a (drop=_type_ _freq_) sum = wt_win_inf;

proc means data = proposals2 noprint; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year; 
  var wt; where q_vote_alpha in (4) and WinVote = 0; 
  output out = win_ret_2b (drop=_type_ _freq_) sum = wt_lose_inf;

proc means data = proposals2 noprint; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year; 
  var wt; where 0 <= q_vote_alpha <= 3 and WinVote = 1; 
  output out = win_ret_2c (drop=_type_ _freq_) sum = wt_win_other;

proc means data = proposals2 noprint; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year; 
  var wt; where 0 <= q_vote_alpha <= 3 and WinVote = 0; 
  output out = win_ret_2d (drop=_type_ _freq_) sum = wt_lose_other;

proc means data = proposals2 noprint; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year; 
  var wt ; where wt > 0 and WinVote = 1;
  output out = win_ret_2e (drop=_type_ _freq_) sum = wt_win ;

proc means data = proposals2 noprint; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year; 
  var wt ; where wt > 0 and WinVote = 0;
  output out = win_ret_2f (drop=_type_ _freq_) sum = wt_lose ;

data proposals3; merge count3 win_ret_2a win_ret_2b win_ret_2c win_ret_2d win_ret_2e win_ret_2f; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year;
  if wt_win_inf = . then wt_win_inf = 0;
  if wt_lose_inf = . then wt_lose_inf = 0;
  net_win_informed = (wt_win_inf-wt_lose_inf); 

  if wt_win_other = . then wt_win_other = 0;
  if wt_lose_other = . then wt_lose_other = 0;
  net_win_uninformed = (wt_win_other-wt_lose_other); 

  if wt_win = . then wt_win = 0;
  if wt_lose = . then wt_lose = 0;
  net_win = wt_win-wt_lose;

  if issformgmt = 1 then iss_win = mgmt_win; else if issformgmt = 0 then iss_win = 1-mgmt_win;

  frac_informed = (wt_win_inf+wt_lose_inf)/mfo;
  informed = wt_win_inf+wt_lose_inf;
  uninformed = mfo-(wt_win_inf+wt_lose_inf);

  if num_mf >= 1;

proc sql;
  create table proposals4 as 
  select *
  from proposals3 as a left join temp.cst_matched as b
  on a.permno = b.permno and intck('day', a.meetingdate, b.meetingdate) = 0;
quit; run; 

proc sql;
  create table proposals4 as
  select a.*, b.*
  from proposals4 as a left join temp.meetings_car_permno as b
  on a.permno = b.permno and intck('day', a.meetingdate, b.meetingdate) = 0;
quit;

*** Fraction of contentious votes in the past 12 months;
proc sql;
  create table proposal_count as
  select a.permno, a.meetingdate, b.num_votes, b.contested20
  from proposals4 as a left join temp.stock_meetings as b
  on a.permno = b.permno and 1 <= intck('month', b.meetingdate, a.meetingdate) <= 12;
quit; * temp.stock_meetings is from 05Meetings_CAR.sas;

proc sort; by permno meetingdate ;

proc means noprint; by permno meetingdate;
  var num_votes contested20;
  output out = proposal_count (drop=_type_ _freq_) sum = num_votes contested20;
run;

proc sql;
  create table proposals4 as 
  select a.*, b.contested20 as n_contested, b.contested20/b.num_votes as frac_contested
  from proposals4 as a left join proposal_count as b
  on a.permno = b.permno and year(a.meetingdate) = year(b.meetingdate) and month(a.meetingdate) = month(b.meetingdate) and day(a.meetingdate) = day(b.meetingdate);
quit;

proc sql;
  create table proposals4 as 
  select a.*, b.issForMgmt as issForMgmt_meeting, b.shrd_sponsored as num_shrd_sponsored, b.mgmt_sponsored as num_mgmt_sponsored, b.iss_win_nc, b.mgmt_win_nc, b.num_votes_nc, b.mgmt_lose_nc_num, b.turnout_c
  from proposals4 as a left join temp.stock_meetings as b
  on a.permno = b.permno and year(a.meetingdate) = year(b.meetingdate) and month(a.meetingdate) = month(b.meetingdate) and day(a.meetingdate) = day(b.meetingdate);
quit;

proc sort data = proposals4; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year;

data proposals4; set proposals4; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year;
  if last.year;
  if ind = . then ind = 48;
  if n_contested = . then n_contested = 0;
  ind_year = ind*10000+year;
  log_nanalyst = log(1+nanalyst);

%winsor(dsetin=proposals4, dsetout=proposals5, byvar=none, vars=net_win_informed net_win_uninformed mfo size mb leverage_b capex sp500 roa, type=winsor, pctl=1 99);

proc sort data = proposals5; by year;

proc rank data = proposals5 out = proposals5 groups = 4; by year;
  var mve_crsp nanalyst;
  ranks r_mve_crsp r_nanalyst;

data proposals5; set proposals5;
  if 0 <= mgmt_win_nc < 1 then mgmt_lost_nc = 1; else mgmt_lost_nc = 0;

proc sort data=proposals5 out = temp.proposals_liq nodupkey; by permno meetingdate itemonagendaid;
   where car63d_dgtw ~= . and iss_win ne . and mb ne . and leverage_b ne . and car63d_ff4 ne . and net_win_informed ne . and net_win_uninformed ne . and mgmt_win ne . and 
     iss_win ne . and size ne . and mb ne . and car_pr252d_m ne . and leverage_b ne . and capex ne . and sp500 ne . and mfo ne . and log_nanalyst ne . and r_illiq2 in (0); *num_63d >= 21 and  and car63d_dgtw ~= . ;
run;

proc export data= temp.proposals_liq 
            outfile= "D:\Dropbox\InformedVoting\proposals_liq.dta" 
            dbms=stata replace;
run;



/* ****************************************************************************************************************************************** */
/* ******************** Confine contentious proposals to those that pass or fail within �10% around the passing threshold *********************/
/* ****************************************************************************************************************************************** */
data temp; set temp.iss_votes_ret;
  if 0 < abs(margin) <= .10 and issue ne '';

proc sort data = temp nodupkey out = proposals (keep=year mend exchcd shrcd rqdate wficn crsp_cl_grp winvote wt permno meetingdate mgmt_sponsored mgmt_win margin agendaGeneralDesc Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue pwt); 
  by wficn crsp_cl_grp mend permno meetingdate wt itemonagendaid; 

proc sort data = proposals out = unique (keep=wficn crsp_cl_grp mend exchcd shrcd) nodupkey; by wficn crsp_cl_grp mend; 

proc sql;
  create table reg as
  select a.wficn, a.crsp_cl_grp, a.mend, b.permno, b.meetingdate, b.itemonagendaid, b.issForMgmt, b.iss_conform, b.car12d_m, b.car12d_m_win, b.WinVote, b.margin, b.mgmt_win, b.market_value_pr2, b.market_value_adj, b.pwt, b.pwt_adj
  from unique as a, test1 as b
  where a.wficn = b.wficn and a.crsp_cl_grp = b.crsp_cl_grp and 1 <= intck('month', b.meetingdate, a.mend) <= 12 and 0 < abs(b.margin) <= .10; 
quit;

proc sort data = reg; by wficn crsp_cl_grp mend; where market_value_adj ne .;

proc means data = reg noprint; by wficn crsp_cl_grp mend; 
  where car12d_m ne .; 
  var WinVote;
  output out = count2 (drop=_type_ _freq_) n = num_votes;

proc means data = reg noprint; by wficn crsp_cl_grp mend; 
  var car12d_m_win ; weight market_value_adj; 
  output out = win_ret_1c (drop=_type_ _freq_) mean = vote_alpha ; 

data measure; merge count2 win_ret_1c; by wficn crsp_cl_grp mend; 

proc sort data = temp.fundinfo nodupkey out = fundinfo; by wficn crsp_cl_grp caldt; where mtna ne .; 

proc sql;
  create table measure as
  select a.*, b.caldt, b.crsp_obj_cd2, b.mtna, b.mtna_adj, b.pct_common_eq
  from measure as a left join fundinfo as b
  on a.wficn = b.wficn and a.crsp_cl_grp = b.crsp_cl_grp and 1 <= intck('month', b.caldt, a.mend) <= 6;
quit;

proc sort; by wficn crsp_cl_grp mend caldt; 

data measure; set measure; by wficn crsp_cl_grp mend caldt; 
  if last.mend;
  if (index(crsp_obj_cd2, 'ED') = 1) and mtna >= 5 and num_votes > 10;  

proc sort; by mend;

proc rank data = measure out  = measure groups = 5; by mend;
  var vote_alpha;
  ranks q_vote_alpha;
run;

proc sort data = measure; by wficn crsp_cl_grp mend; 

data proposals2; merge proposals measure; by wficn crsp_cl_grp mend;
  if wt ne .;
run;

proc sort data = proposals2 nodupkey; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year wficn crsp_cl_grp; 

proc means data = proposals2 noprint; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year;
  var wt; 
  output out = count3 (drop=_type_ _freq_) sum = mfo n = num_mf;

proc sort; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year;

proc means data = proposals2 noprint; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year; 
  var wt; where q_vote_alpha in (4) and WinVote = 1; 
  output out = win_ret_2a (drop=_type_ _freq_) sum = wt_win_inf;

proc means data = proposals2 noprint; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year; 
  var wt; where q_vote_alpha in (4) and WinVote = 0; 
  output out = win_ret_2b (drop=_type_ _freq_) sum = wt_lose_inf;

proc means data = proposals2 noprint; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year; 
  var wt; where 0 <= q_vote_alpha <= 3 and WinVote = 1; 
  output out = win_ret_2c (drop=_type_ _freq_) sum = wt_win_other;

proc means data = proposals2 noprint; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year; 
  var wt; where 0 <= q_vote_alpha <= 3 and WinVote = 0; 
  output out = win_ret_2d (drop=_type_ _freq_) sum = wt_lose_other;

proc means data = proposals2 noprint; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year; 
  var wt; where wt > 0 and WinVote = 1;
  output out = win_ret_2e (drop=_type_ _freq_) sum = wt_win;

proc means data = proposals2 noprint; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year; 
  var wt; where wt > 0 and WinVote = 0;
  output out = win_ret_2f (drop=_type_ _freq_) sum = wt_lose;

data proposals3; merge count3 win_ret_2a win_ret_2b win_ret_2c win_ret_2d win_ret_2e win_ret_2f; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year;
  if wt_win_inf = . then wt_win_inf = 0;
  if wt_lose_inf = . then wt_lose_inf = 0;
  net_win_informed = (wt_win_inf-wt_lose_inf); 
  frac_informed = (wt_win_inf)/(wt_win_inf+wt_lose_inf);

  if wt_win_other = . then wt_win_other = 0;
  if wt_lose_other = . then wt_lose_other = 0;
  net_win_uninformed = (wt_win_other-wt_lose_other); 
  frac_uninformed = wt_win_other/(wt_win_other+wt_lose_other);

  if wt_win = . then wt_win = 0;
  if wt_lose = . then wt_lose = 0;
  net_win = wt_win-wt_lose;

  if issformgmt = 1 then iss_win = mgmt_win; else if issformgmt = 0 then iss_win = 1-mgmt_win;

  if num_mf >= 1;

proc means n mean median p10 p25 p75 p5 p95 min p1 p99 max data = proposals3; where . < abs(margin) <= .1;
  var num_mf net_win_informed net_win_uninformed; run;

proc corr data = proposals3; where . < abs(margin) <= .1;
  var net_win_informed net_win_uninformed; run;

proc sql;
  create table proposals4 as 
  select *
  from proposals3 as a left join temp.cst_matched as b
  on a.permno = b.permno and intck('day', a.meetingdate, b.meetingdate) = 0;
quit; run; 

proc sql;
  create table proposals4 as
  select a.*, b.*
  from proposals4 as a left join temp.meetings_car_permno as b
  on a.permno = b.permno and intck('day', a.meetingdate, b.meetingdate) = 0;
quit;

*** Fraction of contentious votes in the past 12 months;
proc sql;
  create table proposal_count as
  select a.permno, a.meetingdate, b.num_votes, b.contested20
  from proposals4 as a left join temp.stock_meetings as b
  on a.permno = b.permno and 1 <= intck('month', b.meetingdate, a.meetingdate) <= 12;
quit; * temp.stock_meetings is from 05Meetings_CAR.sas;

proc sort; by permno meetingdate ;

proc means noprint; by permno meetingdate;
  var num_votes contested20;
  output out = proposal_count (drop=_type_ _freq_) sum = num_votes contested20;
run;

proc sql;
  create table proposals4 as 
  select a.*, b.contested20 as n_contested, b.contested20/b.num_votes as frac_contested
  from proposals4 as a left join proposal_count as b
  on a.permno = b.permno and year(a.meetingdate) = year(b.meetingdate) and month(a.meetingdate) = month(b.meetingdate) and day(a.meetingdate) = day(b.meetingdate);
quit;

proc sql;
  create table proposals4 as 
  select a.*, b.issForMgmt as issForMgmt_meeting, b.shrd_sponsored as num_shrd_sponsored, b.mgmt_sponsored as num_mgmt_sponsored, b.iss_win_nc, b.mgmt_win_nc, b.num_votes_nc, b.mgmt_lose_nc_num, b.turnout_c
  from proposals4 as a left join temp.stock_meetings as b
  on a.permno = b.permno and year(a.meetingdate) = year(b.meetingdate) and month(a.meetingdate) = month(b.meetingdate) and day(a.meetingdate) = day(b.meetingdate);
quit;

proc sort data = proposals4; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year;

data proposals4; set proposals4; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year;
  if last.year;
  if ind = . then ind = 48;
  if n_contested = . then n_contested = 0;
  ind_year = ind*10000+year;
  log_nanalyst = log(1+nanalyst);
  if 0 <= mgmt_win_nc < 1 then mgmt_lost_nc = 1; else mgmt_lost_nc = 0;

%winsor(dsetin=proposals4, dsetout=proposals4, byvar=none, vars=net_win_informed net_win_uninformed mfo size mb leverage_b capex sp500 roa, type=winsor, pctl=1 99);

proc sort data = proposals4; by year;

proc sort data=proposals4 out = temp.proposals10 nodupkey; by permno meetingdate itemonagendaid;
   where car63d_dgtw ~= . and iss_win ne . and mb ne . and leverage_b ne . and car63d_ff4 ne . and net_win_informed ne . and net_win_uninformed ne . and mgmt_win ne . and 
     iss_win ne . and size ne . and mb ne . and car_pr252d_m ne . and leverage_b ne . and capex ne . and sp500 ne . and mfo ne . and log_nanalyst ne .; *num_63d >= 21 and  and car63d_dgtw ~= . ;
run;

proc export data= temp.proposals10 
            outfile= "D:\Dropbox\InformedVoting\proposals10.dta" 
            dbms=stata replace;
run;



/* ************************************************************************************************************************ */
/* ******************** Expand the sample of contentious governance proposals to include proxy contests *********************/
/* ************************************************************************************************************************ */
data proxy_contest; set iss.Vote_Results2003_2018 (drop=votes1yr votes2yr votes3yr);
  if ISSAgendaItemID in ('M0299', 'S0299');
  if voteResult in ('Pass', 'Fail');
  if ISSAgendaItemID = 'S0299' and mgmtrec = 'For' then mgmtrec = 'Against'; * correct data errors;
  if companyID = 27874 and meetingid = 444429 then delete; * Charming Shoppes, Inc.: settlement reached before the vote;
  if companyID = 150434 and meetingid = 1235930 and ISSAgendaItemID = 'S0299' and itemDesc in ('Elect Director Michael J. Embler', 'Elect Director Mayree C. Clark') then delete; * Taubman Centers, Inc.: duplicate entries for two management nominees;
  if companyID = 151871 and meetingid = 471554 then delete; * Texas Industries, Inc. 2008: withholding campaign;
  if companyID = 513353 and meetingid = 508698 then delete; * Saks Incorporated 2009: withholding campaign;
  if companyID = 535941 and meetingid = 823156 then delete; * MGP Ingredients, Inc.: not a proxy contest, just two classes of shares;
  if companyID = 543413 and meetingid = 516544 then delete; * iPass Inc.: uncontested election, agreement reached before the vote;
  if companyID = 551157 and meetingid = 795363 then delete; * Tessera Technologies, Inc.: uncontested election, agreement reached before the vote;
  if companyID = 562621 and meetingid = 497117 then delete; * CF Industries Holdings, Inc. 2009: withholding campaign; 
  if companyID = 566498 and meetingid = 928942 then delete; * Cardica, Inc.: uncontested election, agreement reached before the vote; 
  if companyID = 577688 and meetingid = 976542 then delete; * Essex Rental Corp.: uncontested election, agreement reached before the vote; 
  if companyID = 581655 and meetingid = 1239043 then delete; * SandRidge Energy, Inc.: uncontested election, agreement reached before the vote, 6 nominees (2 management + 4 Icahn) for 6 open seats;
  if companyID = 585860 and meetingid = 885500 then delete; * Solera National Bancorp, Inc.: Court case pending: https://www.sec.gov/Archives/edgar/data/1357231/000135723114000064/a8kdoc2014meetingresults.htm;
  if companyID = 590449 and meetingid = 1006605 then delete; * Anchor Bancorp: Dissident won the most votes but was not eligible to serve as a director, board agreed to add one more seat ;
  if companyID = 567681 and meetingid = 722291 then delete; * Macquarie Global Infrastructure Total Return Fund Inc.: A quorum was present but neither nominee received a sufficient number of votes to be elected: 
     https://www.sec.gov/Archives/edgar/data/1326390/000132639013000004/mguvotingresults.htm;
  if ISSAgendaItemID = 'S0299' and index(upcase(ItemDesc), 'MANAGEMENT NOMINEE') > 0 then delete;

  if companyID = 21681 and meetingid = 523767 then do;
    if ItemOnAgendaId in (7809763, 7809764) then votedFor = 2580993; *CPI CORP: https://www.sec.gov/Archives/edgar/data/25354/000002535409000064/exh99_1.htm;
  end;
  votes_all = votedFor+votedAgainst+votedAbstain;
  
proc sort; by CompanyId Name ticker CUSIP MeetingID;

proc means noprint; by CompanyId Name ticker CUSIP MeetingID;
  var votes_all;
  output out = meeting_level (drop=_freq_ _type_) mean(votes_all) = votes_all_mean max(votes_all) = all_votes;

data proxy_contest; merge proxy_contest meeting_level; by CompanyId Name ticker CUSIP MeetingID;
  if votes_all_mean = 0 then not_voted = 1; 
  drop votes_all votes_all_mean; 

proc sort data = proxy_contest; by CompanyId Name ticker CUSIP MeetingID MeetingDate Recorddate sponsor ISSAgendaItemID;

proc means noprint; by CompanyId Name ticker CUSIP MeetingID MeetingDate Recorddate sponsor ISSAgendaItemID;
  var ItemOnAgendaId;
  output out = proxy_contest_meeting_level (drop=_type_ _freq_) n = num_nominees mean(not_voted) = not_voted;

data proxy_contest_meeting_level1a; set proxy_contest_meeting_level; by CompanyId Name ticker CUSIP MeetingID MeetingDate Recorddate;
  if ISSAgendaItemID = 'M0299';
  mgmt_num_nominees = num_nominees;
  open_seats = mgmt_num_nominees;
  if companyID = 17412 and meetingid = 908764 then open_seats = 12; * Bob Evans;
  if companyID = 31255 and meetingid = 903342 then open_seats = 11; * Cliffs Natural Resources Inc.;
  if companyID = 39285 and meetingid = 1136674 then open_seats = 7; * Cypress Semiconductor Corp.;
  if companyID = 40166 and meetingid = 911527 then open_seats = 12; * Darden Restaurants, Inc.;
  if companyID = 52999 and meetingid = 792928 then open_seats = 3; * Ferro Corporation;
  if companyID = 141050 and meetingid = 734937 then open_seats = 4; * Sigma Designs, Inc.;
  if companyID = 150434 and meetingid = 1235930 then open_seats = 3; * Taubman Centers, Inc.;
  if companyID = 526550 and meetingid = 1063000 then open_seats = 6; * Support.com, Inc.;
  if companyID = 551831 and meetingid = 1142053 then open_seats = 9; * Buffalo Wild Wings, Inc.; 
  if companyID = 566489 and meetingid = 791703 then open_seats = 7; * Morgans Hotel Group Co.;
  if companyID = 601793 and meetingid = 1055135 then open_seats = 3; * Green Dot Corporation;
  if companyID = 104943 and meetingid = 960781 then open_seats = 9; * Myers Industries, Inc.;
run;

data proxy_contest_meeting_level1b; set proxy_contest_meeting_level; by CompanyId Name ticker CUSIP MeetingID MeetingDate Recorddate;
  if ISSAgendaItemID = 'S0299';
  shrhdr_num_nominees = num_nominees;

data proxy_contest_meeting_level2; merge proxy_contest_meeting_level1a (in=a) proxy_contest_meeting_level1b (in=b); by CompanyId Name ticker CUSIP MeetingID MeetingDate Recorddate;
  if a and b;
  year = year(MeetingDate);
  if not_voted ne 1; * remove proxy contests that do not lead to a vote; 
  if MeetingDate <= '30jun2018'd;
  keep year CompanyId Name ticker CUSIP MeetingID MeetingDate Recorddate mgmt_num_nominees open_seats shrhdr_num_nominees;
run;

data proxy_contest2; merge proxy_contest proxy_contest_meeting_level2 (in=b); by CompanyId Name ticker CUSIP MeetingID MeetingDate Recorddate;
  if b; 
  drop not_voted;
run;

proc sort; by CompanyId Name ticker CUSIP MeetingID MeetingDate Recorddate descending votedfor;

data proxy_contest2; set proxy_contest2; by CompanyId Name ticker CUSIP MeetingID MeetingDate Recorddate descending votedfor;
  if first.Recorddate then i = 0;
  i+1;
  if i > open_seats then do; voteResult2 = 'Fail'; elected = 0; end; 
    else if i <= open_seats then do; voteResult2 = 'Pass'; elected = 1; end;

proc sort data = proxy_contest2; by CompanyId Name ticker CUSIP MeetingID MeetingDate Recorddate ISSAgendaItemID;

proc means noprint; by CompanyId Name ticker CUSIP MeetingID MeetingDate Recorddate ISSAgendaItemID;
  var elected;
  output out = win_lose (drop=_type_ _freq_) mean = frac_elected;

data win_lose1a; set win_lose; by CompanyId Name ticker CUSIP MeetingID MeetingDate Recorddate;
  if ISSAgendaItemID = 'M0299'; 
  mgmt_frac_elected = frac_elected;

data win_lose1b; set win_lose; by CompanyId Name ticker CUSIP MeetingID MeetingDate Recorddate;
  if ISSAgendaItemID = 'S0299';
  diss_frac_elected = frac_elected;

data win_lose2; merge win_lose1a win_lose1b; by CompanyId Name ticker CUSIP MeetingID MeetingDate Recorddate;
  if mgmt_frac_elected = 1 then dissident_win = 0;
  if diss_frac_elected > 0 then dissident_win = 1;
  year = year(MeetingDate);
  keep CompanyId Name ticker CUSIP MeetingID MeetingDate Recorddate mgmt_frac_elected diss_frac_elected dissident_win year;
run;

data temp.proxy_contest; merge proxy_contest2 win_lose2; by CompanyId Name ticker CUSIP MeetingID MeetingDate Recorddate;
  year = year(MeetingDate);

proc sort nodupkey; by itemonagendaid;
run;


proc sql;
  create table votes_contests as
  select a.*, b.votedfor, b.dissident_win
  from issNEW.Voteanalysis_npx (keep=institutionName institutionID FundId FundName CompanyID CompanyName SecurityID version meetingID MeetingDate ISSAgendaItemID itemonagendaid agendageneraldesc 
    seqNumber BallotItemNumber ItemDesc FundVote) as a, temp.proxy_contest as b
  where a.itemOnAgendaId = b.itemOnAgendaId; 
quit;

data votes_contests; set votes_contests;
  year = year(MeetingDate);
  yymm = year(MeetingDate)*100+month(MeetingDate);

proc sort data = votes_contests nodupkey; by _all_;
run;


*** voted proxy contests with mutual funds' votes;
proc sort data = votes_contests out = voted nodupkey; by CompanyId MeetingID MeetingDate;

proc sort data = iss.Vote_Results2003_2018 (keep=companyid meetingID cusip ticker recordDate) out = identifier nodupkey; by companyid meetingID ticker cusip;

proc sort data = identifier (keep=companyid ticker cusip) out = identifier2 nodupkey; by companyid; 

proc sort data = votes_contests (keep=companyid meetingID CompanyName SecurityID MeetingDate) out = votes_identifier nodupkey; by companyid meetingID; 

proc sql;
  create table votes_identifier2 as
  select a.*, b.ticker, b.cusip, recordDate
  from votes_identifier as a left join identifier as b
  on a.companyid = b.companyid and a.meetingID = b.meetingID;
quit;

data votes_identifier2a; set votes_identifier2;
  if ticker ne ''; 

data votes_identifier2b; set votes_identifier2;
  if ticker = ''; 
  drop ticker cusip recordDate;

proc sql;
  create table votes_identifier2b as 
  select a.*, b.ticker, b.cusip
  from votes_identifier2b as a, identifier2 as b
  where a.companyid = b.companyid;
quit;

data votes_identifier3; set votes_identifier2a votes_identifier2b;
run;

proc sql;
  create table votes_contests1 as
  select a.*, b.ticker, b.cusip, recordDate
  from votes_contests as a, votes_identifier3 as b
  where a.companyid = b.companyid and a.meetingID = b.meetingID;
quit;

proc sql;
  create table votes_contests1 as
  select a.*, b.mgmtrec as mgtrecvote, b.issrec as issrecvote, b.voteResult, b.voteResult2, b.base
  from votes_contests1 as a, temp.proxy_contest as b
  where a.itemonagendaid = b.itemonagendaid;
quit;

proc sort nodupkey; by _ALL_;

data votes_contests1; set votes_contests1;
  if fundvote not in ('<Unknown>', 'Do Not Vote', 'None') then voteWithMgmt = 0;
  if mgtrecvote = "Abstain" and fundvote = "Abstain" then voteWithMgmt=1;
  if mgtrecvote = "Withhold" and fundvote = "Withhold" then voteWithMgmt=1;
  if mgtrecvote = "Against" and fundvote = "Against" then voteWithMgmt=1; 
  if mgtrecvote = "For" and fundvote = "For" then voteWithMgmt=1;
  if mgtrecvote = "One Year" and fundvote = "One Year" then voteWithMgmt=1;
  if mgtrecvote = "Two Years" and fundvote = "Two Years" then voteWithMgmt=1;
  if mgtrecvote = "Three Years" and fundvote = "Three Years" then voteWithMgmt=1;
  if mgtrecvote = "Do Not Vote" and fundvote = "Do Not Vote" then voteWithMgmt=1;
  if mgtrecvote = "For" and fundvote in ("Abstain", "Withhold", "Do Not Vote", "None") then voteWithMgmt=0;
  if mgtrecvote = "Against" and fundvote in ("Abstain", "Withhold", "Do Not Vote", "None") then voteWithMgmt=1;

  if mgtrecvote ne '' then mgmtFor=0;
  if mgtrecvote = "For" then mgmtFor=1;

  if fundvote ne '' then fundFor=0;
  if fundvote = "For" then fundFor=1;
  
  if fundvote ne '' then fundAgainst=0;
  if fundvote = "Against" then fundAgainst=1;

  if voteResult = 'Pass' then do;
    if fundvote = "For" then WinVote = 1; else 
    if fundvote = "Against" then WinVote = 0; else 
    if fundvote in ("Abstain", "Withhold", "Do Not Vote", "None") then WinVote = 0; end;

  if voteResult = 'Fail' then do;
    if fundvote = "Against" then WinVote = 1; else 
    if fundvote = "For" then WinVote = 0; else 
	if fundvote in ("Abstain", "Withhold", "Do Not Vote", "None") then WinVote = 1; end;

  if substr(issagendaitemid,1,1) = "S" then mgmt_sponsored = 0;
  if substr(issagendaitemid,1,1) = "M" then mgmt_sponsored = 1;

  if mgtrecvote = issrecvote and mgtrecvote in ("For", "Against") then issForMgmt=1; else 
  if mgtrecvote ne issrecvote and mgtrecvote in ("For", "Against") and issrecvote in ("For", "Against") then issForMgmt=0; else
  if (mgtrecvote = "Abstain" or index(mgtrecvote, "Do Not V") = 1) and issrecvote in ("Abstain", "Do Not Vote", "Withhold", "None") then issForMgmt=1; else
  if mgmt_sponsored = 1 and issrecvote in ("For") then issForMgmt=1; else
  if mgmt_sponsored = 1 and issrecvote in ("Do Not Vote", "Withhold") then issForMgmt=0; else
  if mgmt_sponsored = 0 and issrecvote in ("Against", "Abstain", "Do Not Vote", "Withhold") then issForMgmt=1; else
  if mgmt_sponsored = 0 and issrecvote in ("For") then issForMgmt=0; else
  if mgtrecvote = "Withhold" and issrecvote in ("Abstain", "Do Not Vote", "Withhold") then issForMgmt=1; else
  if substr(upcase(mgtrecvote), 1, 3) = substr(upcase(issrecvote), 1, 3) and index(upcase(mgtrecvote), "YE") > 0 and index(upcase(issrecvote), "YE") > 0 then issForMgmt=1; else
  if substr(upcase(mgtrecvote), 1, 3) ne substr(upcase(issrecvote), 1, 3) and index(upcase(mgtrecvote), "YE") > 0 and index(upcase(issrecvote), "YE") > 0 then issForMgmt=0;


  if fundvote = issrecvote and fundvote in ("For", "Against") then iss_conform=1; else 
  if fundvote ne issrecvote and fundvote in ("For", "Against") and issrecvote in ("For", "Against") then iss_conform=0; else
  if (fundvote = "Abstain" or index(fundvote, "Do Not V") = 1) and issrecvote in ("Abstain", "Do Not Vote", "Withhold", "None") then iss_conform=1; else
  if fundvote = "Withhold" and issrecvote in ("Abstain", "Do Not Vote", "Withhold") then iss_conform=1; else
  if substr(upcase(fundvote), 1, 3) = substr(upcase(issrecvote), 1, 3) and index(upcase(fundvote), "YE") > 0 and index(upcase(issrecvote), "YE") > 0 then iss_conform=1; else
  if substr(upcase(fundvote), 1, 3) ne substr(upcase(issrecvote), 1, 3) and index(upcase(fundvote), "YE") > 0 and index(upcase(issrecvote), "YE") > 0 then iss_conform=0;

  if WinVote not in (0, 1) then delete;

proc sort data = votes_contests1; by institutionID fundid companyID cusip companyName meetingID meetingdate ISSAgendaItemID fundvote; 

proc means noprint; by institutionID fundid companyID cusip companyName meetingID meetingdate ISSAgendaItemID fundvote; 
  var seqNumber;
  output out = votes_contests2 (drop=_type_ _freq_) n = num_votes;
run;

proc sort data = votes_contests1 nodupkey out = list (keep=institutionID fundid companyID cusip ticker companyName meetingID meetingdate ISSAgendaItemID mgmt_sponsored itemonagendaid ItemDesc votedfor voteWithMgmt WinVote iss_conform); 
  by institutionID fundid companyID companyName meetingID meetingdate ISSAgendaItemID descending votedfor itemonagendaid; 
  where ISSAgendaItemID = 'S0299';

data list; set list; by institutionID fundid companyID companyName meetingID meetingdate ISSAgendaItemID;
  if first.ISSAgendaItemID; * keep the dissent nominee with the highest for votes;

proc sort data = votes_contests2 nodupkey out = votes_contests2a (keep=institutionID fundid companyID cusip companyName meetingID meetingdate fundvote); 
  by institutionID fundid companyID companyName meetingID meetingdate;
  where ISSAgendaItemID = 'S0299' and fundvote = 'For';

data votes_contests2a; merge list votes_contests2a (in=a); by institutionID fundid companyID cusip companyName meetingID meetingdate;
  if a then voteForDis = 1; else voteForDis = 0;

proc sort; by companyID companyName meetingID meetingdate;

proc sort data = votes_contests1 nodupkey out = votes_contests2b (keep=companyID cusip companyName meetingID meetingdate issForMgmt); 
  by companyID companyName meetingID meetingdate;
  where ISSAgendaItemID = 'S0299' and issForMgmt = 0;

data temp.votes_contests; merge votes_contests2a votes_contests2b (in=b); by companyID cusip companyName meetingID meetingdate;
  if b then issForMgmt = 0; else issForMgmt = 1; * issForMgmt is an indicator that equals one if ISS recommend voting against management on at least one dissident nominee;
  year = year(MeetingDate);
  issue = 'Contest';

proc sort data = temp.votes_contests nodupkey; by cusip meetingID meetingdate mgmt_sponsored issAgendaItemId itemonagendaid institutionid fundid fundvote;
run;

* add PERMNO - note obs with no match drop;
proc sort data=crsp.stocknames(keep=permno ncusip cusip ticker namedt nameenddt shrcd exchcd where=(not missing(ncusip))) 
  out=cusips nodupkey; by permno ncusip;

proc sql;
  create table votes_contests_results2 as
  select a.*, b.permno, min(intck('month', b.namedt, a.meetingdate), intck('month', a.meetingdate, b.nameenddt)) as dist
  from temp.votes_contests as a left join cusips as b
  on substr(a.cusip, 1, 8) = substr(b.ncusip, 1, 8) and b.namedt <= a.meetingdate <= nameenddt;
quit;

proc sort; by cusip meetingdate mgmt_sponsored Itemdesc issAgendaItemId itemonagendaid institutionid fundid issForMgmt fundvote issue dist;

data votes_contests_results2; set votes_contests_results2; by cusip meetingdate mgmt_sponsored Itemdesc issAgendaItemId itemonagendaid institutionid fundid issForMgmt fundvote issue dist;
  if first.issue;

data votes_contests_results2a; set votes_contests_results2; 
  if dist ne .;

data votes_contests_results2; set votes_contests_results2; 
  if dist = .; 
  drop permno dist;
run;

proc sql;
  create table votes_contests_results2 as
  select a.*, b.permno, min(intck('month', b.namedt, a.meetingdate), intck('month', a.meetingdate, b.nameenddt)) as dist
  from votes_contests_results2 as a left join cusips as b
  on substr(a.cusip, 1, 6) = substr(b.ncusip, 1, 6) and a.ticker = b.ticker and b.namedt <= a.meetingdate <= nameenddt;
quit;

data votes_contests_results2b; set votes_contests_results2; 
  if dist ne .;

data votes_contests_results2c; set votes_contests_results2; 
  if dist = .; 
  drop permno dist;
run;

proc sql;
  create table votes_contests_results2x as
  select a.*, b.permno, min(abs(intck('month', b.namedt, a.meetingdate)), abs(intck('month', a.meetingdate, b.nameenddt))) as dist
  from votes_contests_results2c as a left join cusips as b
  on substr(a.cusip, 1, 8) = substr(b.ncusip, 1, 8); 
quit;

proc sort; by cusip meetingdate mgmt_sponsored Itemdesc issAgendaItemId itemonagendaid institutionid fundid issForMgmt fundvote issue dist;

data votes_contests_results2c; set votes_contests_results2x; by cusip meetingdate mgmt_sponsored Itemdesc issAgendaItemId itemonagendaid institutionid fundid issForMgmt fundvote issue dist;
  if first.issue;
  if permno ne .; 
run;

data votes_contests_results3 (compress=yes); set votes_contests_results2a (in=a) votes_contests_results2b (in=b) votes_contests_results2c (in=c);
  if a then s = 1; 
  if b then s = 2; 
  if c then s = 3; 
run;

**** Link to holdings data;
proc sort data = votes_contests_results3 out = fund_mend0 (keep=institutionID fundid meetingdate) nodupkey; by institutionID fundid meetingdate;

data fund_mend; set fund_mend0;
  mend = intnx('month', meetingdate, 0, 'end');
  format mend date9.;

proc sql;
  create table fund_mend as
  select a.*, b.institutionName, b.fundname, b.crsp_fundno, b.wficn, b.crsp_cl_grp
  from fund_mend as a, drop.iss_crspmf as b
  where a.institutionID = b.institutionID and a.fundid = b.fundid; * and intck('month', a.meetingdate, b.mend) = 0;
quit;

proc sort nodupkey data = fund_mend; by institutionID fundid mend wficn; 
run;


proc sort data = temp.s12_holdings (keep=wficn rdate fdate) nodupkey out = s12_dates; by wficn rdate fdate;
run; * temp.s12_holdings is from 02Holdings.sas;

proc sql;
  create table wficn_mend as
  select a.*, b.rdate, b.fdate
  from fund_mend as a left join s12_dates as b
  on a.wficn = b.wficn and 1 <= intck('month', b.rdate, a.mend) <= 6;
quit;

proc sort data = wficn_mend; by institutionID fundid mend wficn descending rdate fdate; 

data wficn_mend; set wficn_mend; by institutionID fundid mend wficn descending rdate; 
  if first.wficn;
run;

proc sql;
  create table votes_contests_results3a as
  select a.*, b.crsp_cl_grp, b.wficn, b.rdate, b.fdate
  from votes_contests_results3 as a left join wficn_mend as b
  on a.institutionID = b.institutionID and a.fundid = b.fundid and year(a.meetingdate) = year(b.mend) and month(a.meetingdate) = month(b.mend);
quit;

proc sort data = votes_contests_results3a; by wficn crsp_cl_grp permno meetingdate rdate fdate mgmt_sponsored Itemdesc issAgendaItemId itemonagendaid issForMgmt issue; 

proc means data = votes_contests_results3a noprint; by wficn crsp_cl_grp permno meetingdate rdate fdate mgmt_sponsored Itemdesc issAgendaItemId itemonagendaid issForMgmt issue; 
  var voteWithMgmt winVote iss_conform;
  output out = votes_contests_results3a (drop=_type_ _freq_) mean = voteWithMgmt winVote iss_conform;
run;

***** LINK TO S12 holdings;
proc sql;
  create table votes_contests_results3s as
  select a.*, b.market_value, b.shares_adj as nbr_shares, b.wt_adj as wt, b.pwt, b.cfacshr_rdate
  from votes_contests_results3a as a left join temp.s12_holdings as b
  on a.wficn = b.wficn and a.rdate = b.rdate and a.fdate = b.fdate and a.permno = b.permno;
quit; * temp.s12_holdings is from 02Holdings.sas;
run;



***** LINK TO CRSPMF holdings;
data votes_contests_results3x; set votes_contests_results3s;
  if wt = .; 

proc sort data = votes_contests_results3x out = no_s12 (keep=wficn crsp_cl_grp permno meetingdate) nodupkey; by crsp_cl_grp meetingdate permno;

proc means noprint; by crsp_cl_grp meetingdate;
  var permno;
  output out = num_stox (drop=_type_ _freq_) n = no_stocks;

proc sort data = no_s12 (keep=wficn crsp_cl_grp meetingdate) nodupkey; by crsp_cl_grp meetingdate;

data no_s12; merge no_s12 num_stox; by crsp_cl_grp meetingdate;

proc sort data = temp.holdings out = fund_dates (keep=crsp_cl_grp report_dt) nodupkey; by crsp_cl_grp report_dt;

proc sql;
  create table no_s12 as
  select a.*, b.report_dt as rdate
  from no_s12 as a left join fund_dates as b
  on a.crsp_cl_grp = b.crsp_cl_grp and 1 <= intck('month', b.report_dt, a.meetingdate) <= 6;
quit;

proc sort data = no_s12; by crsp_cl_grp meetingdate rdate;

data no_s12; set no_s12; by crsp_cl_grp meetingdate rdate;
  if last.meetingdate and rdate ne . and crsp_cl_grp ne .;

proc sql;
  create table votes_contests_results3x as
  select a.*, b.rdate
  from votes_contests_results3x (drop=rdate fdate market_value nbr_shares wt cfacshr_rdate pwt) as a left join no_s12 as b
  on a.crsp_cl_grp = b.crsp_cl_grp and a.meetingdate = b.meetingdate;
quit;
 
proc sql;
  create table votes_contests_results3x as
  select a.*, b.nbr_shares, b.wt, b.pwt, b.cfacshr_rdate
  from votes_contests_results3x as a, temp.holdings as b
  where a.crsp_cl_grp = b.crsp_cl_grp and a.rdate = b.report_dt and a.permno = b.permno;
quit;run; * temp.holdings is from 02Holdings.sas;
    
proc sort data = votes_contests_results3x; by wficn permno meetingdate rdate mgmt_sponsored Itemdesc issAgendaItemId itemonagendaid issForMgmt issue voteWithMgmt winVote iss_conform; 
  where permno ne . and crsp_cl_grp ne . and wt ne .;
 
proc sort data = votes_contests_results3s; by wficn permno meetingdate rdate mgmt_sponsored Itemdesc issAgendaItemId itemonagendaid issForMgmt issue voteWithMgmt winVote iss_conform; 
  where permno ne . and wficn ne . and wt ne .;

data votes_contests_results3b; set votes_contests_results3s (in=a) votes_contests_results3x (in=b);
  if a then s12 = 1; if b then s12 = 0;
run;
 
proc sql;
  create table votes_contests_results3b as
  select a.*, b.mgmtrec as mgtrecvote, b.voteResult2 as voteResult
  from votes_contests_results3b as a left join temp.proxy_contest as b
  on a.itemOnAgendaId = b.itemOnAgendaId; 
quit;

*** retrieve common stocks;
proc sort data=crsp.stocknames(keep=permco permno ncusip cusip ticker comnam namedt nameenddt st_date end_date shrcd exchcd where=(not missing(ncusip))) 
  out=permno nodupkey; by permno namedt nameenddt;
run;

proc sql;
  create table votes_contests_results4 as
  select a.*, b.shrcd, b.exchcd
  from votes_contests_results3b as a left join permno as b
  on a.permno = b.permno and b.namedt <= a.meetingdate <= b.nameenddt;
quit;

proc sort data = votes_contests_results4 nodupkey; by _ALL_; 
run;

data temp.votes_contests_ret; set votes_contests_results4; 
  if mgtrecvote = 'Against' then do;
    if voteresult = 'Pass' then mgmt_win = 0; else if voteresult = 'Fail' then mgmt_win = 1; end;
  if mgtrecvote = 'For' then do;
    if voteresult = 'Pass' then mgmt_win = 1; else if voteresult = 'Fail' then mgmt_win = 0; end;

  rqdate = intnx('quarter', meetingdate, -1, 'end');
  qtr = year(rqdate)*10+qtr(rqdate);
  fundid_permno = wficn*100000+permno;
  mend = intnx('month', meetingdate, 0, 'end');
  fundid_qtr = wficn*10000+qtr;
  fundid_year = wficn*1000+year(meetingdate);
  permno_meeting = meetingdate*1000000+meetingdate;
  if WinVote ne .; * and wt ne . and p_wt ne .;
  if nanalyst = . then nanalyst = 0;

  year = year(meetingdate);
  voteAgainstMgmt = 1-voteWithMgmt;

proc sort; by wficn crsp_cl_grp permno meetingdate itemonagendaid;
run; 


proc sort data = temp.iss_votes_ret nodupkey out = proposals (keep=year mend exchcd shrcd rqdate wficn crsp_cl_grp winvote wt permno meetingdate mgmt_sponsored mgmt_win margin Itemdesc issAgendaItemId itemonagendaid issForMgmt issue pwt); 
  by wficn crsp_cl_grp mend permno meetingdate wt itemonagendaid; 
  where 0 < abs(margin) <= .20 and issue ne '';

proc sort data = temp.votes_contests_ret nodupkey out = proposals_ (keep=year mend exchcd shrcd rqdate wficn crsp_cl_grp winvote wt permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid issForMgmt issue pwt); 
  by wficn crsp_cl_grp mend permno meetingdate wt itemonagendaid; 

data proposals_incl_contests; set proposals proposals_; 

proc sort; by wficn crsp_cl_grp mend permno meetingdate wt itemonagendaid; 
run;

proc sort data = proposals_incl_contests out = unique_permno (keep=permno mend exchcd shrcd) nodupkey; by permno mend; 
run;

**** Retrieve for each fund-proposal, the past votes and returns; 
data test; set temp.iss_votes_ret;
  if issForMgmt = 1 then iss_win = mgmt_win;
  if issForMgmt = 0 then iss_win = -mgmt_win;
  month = month(meetingdate);
  yyyymm = year(meetingdate)*100+month;
  where 0 < abs(margin) <= .20 and issue ne '';

/* Add proxy contests; */
data test_; set temp.votes_contests_ret;
  if issForMgmt = 1 then iss_win = mgmt_win;
  if issForMgmt = 0 then iss_win = -mgmt_win;
  month = month(meetingdate);
  yyyymm = year(meetingdate)*100+month;

data test; set test (in=a) test_ (in=b); 
  if a then contest = 0;
  if b then contest = 1;
run;

****** Proxy contest returns;
data permno_dates_; set iss.Vote_Results2003_2018;
  if ISSAgendaItemID in ('S0299');
  if substr(issagendaitemid,1,1) = "S" then mgmt_sponsored = 0;
  if substr(issagendaitemid,1,1) = "M" then mgmt_sponsored = 1;

  if substr(issagendaitemid,1,1) = "S" then shrd_sponsored = 1;
  if substr(issagendaitemid,1,1) = "M" then shrd_sponsored = 0;


  if mgmtrec = issrec and mgmtrec in ("For", "Against") then issForMgmt=1; else 
  if mgmtrec ne issrec and mgmtrec in ("For", "Against") and issrec in ("For", "Against") then issForMgmt=0; else
  if (mgmtrec = "Abstain" or index(mgmtrec, "Do Not V") = 1) and issrec in ("Abstain", "Do Not Vote", "Withhold", "None") then issForMgmt=1; else
  if mgmt_sponsored = 1 and issrec in ("For") then issForMgmt=1; else
  if mgmt_sponsored = 1 and issrec in ("Do Not Vote") then issForMgmt=0; else
  if mgmtrec = "Withhold" and issrec in ("Abstain", "Do Not Vote", "Withhold") then issForMgmt=1; else
  if substr(upcase(mgmtrec), 1, 3) = substr(upcase(issrec), 1, 3) and index(upcase(mgmtrec), "YE") > 0 and index(upcase(issrec), "YE") > 0 then issForMgmt=1; else
  if substr(upcase(mgmtrec), 1, 3) ne substr(upcase(issrec), 1, 3) and index(upcase(mgmtrec), "YE") > 0 and index(upcase(issrec), "YE") > 0 then issForMgmt=0;

  turnout = (votedfor+votedagainst+votedabstain)/outstandingShare;
  if votedfor+votedagainst <= 1 then delete; 
  issue = 'Contest';

data permno_dates_; set permno_dates_;
  if base in ('F+A', 'F A') then margin = votedfor/(votedfor+votedagainst)-voterequirement;
  if base in ('F+A+AB', 'F A AB') then margin = votedfor/(votedfor+votedagainst+votedabstain)-voterequirement;
  if base = 'Outstanding' then margin = votedfor/outstandingshare-voterequirement;
  if . < abs(margin) <= .2 then contested20 = 1; else if margin ne . then contested20 = 0;
  if . < abs(margin) <= .1 then contested10 = 1; else if margin ne . then contested10 = 0;
  if . < abs(margin) <= .05 then contested5 = 1; else if margin ne . then contested5 = 0;
  abs_margin = abs(margin);

  if MGMTrec = 'Against' then do;
    if voteresult = 'Pass' then do; mgmt_win = 0; margin_mgmt = -abs(margin); end; else if voteresult = 'Fail' then do; mgmt_win = 1; margin_mgmt = abs(margin); end; end;
  if MGMTrec = 'For' then do;
    if voteresult = 'Pass' then do; mgmt_win = 1; margin_mgmt = abs(margin); end; else if voteresult = 'Fail' then do; mgmt_win = 0; margin_mgmt = -abs(margin); end; end;

  if issformgmt = 1 then iss_win = mgmt_win; else if issformgmt = 0 then iss_win = 1-mgmt_win;

proc sort data = permno_dates_ ; by companyid meetingID meetingDate cusip ticker recordDate; 

proc means data = permno_dates_ noprint; by companyid meetingID meetingDate cusip ticker recordDate; 
  var iss_win mgmt_win abs_margin; where contested20 = 0;
  output out = permno_dates_1a (drop=_type_ _freq_) n(mgmt_win) = num_votes_nc mean = iss_win_nc mgmt_win_nc abs_margin sum(mgmt_win) = mgmt_win_nc_num; run;

proc means data = permno_dates_ noprint; by companyid meetingID meetingDate cusip ticker recordDate; 
  var contested20 contested10 contested5 iss_win mgmt_win issForMgmt shrd_sponsored mgmt_sponsored;
  output out = permno_dates_1b (drop=_type_ _freq_) n(mgmt_win) = num_votes sum = contested20 contested10 contested5 iss_win mgmt_win issForMgmt shrd_sponsored mgmt_sponsored; run;

proc means data = permno_dates_ noprint; by companyid meetingID meetingDate cusip ticker recordDate; 
  var turnout; where contested20 = 1;
  output out = permno_dates_1c (drop=_type_ _freq_) mean = turnout_c; run;

data permno_dates_1; merge permno_dates_1a permno_dates_1b permno_dates_1c; by companyid meetingID meetingDate cusip ticker recordDate; 
  mgmt_lose_nc_num = num_votes_nc-mgmt_win_nc_num;

* add PERMNO - note obs with no match drop;
proc sort data=crsp.stocknames(keep=permno ncusip cusip ticker namedt nameenddt shrcd exchcd siccd where=(not missing(ncusip))) 
  out=cusips nodupkey; by permno ncusip namedt nameenddt;
run;

proc sql;
  create table permno_dates_2 as
  select a.*, b.permno, min(intck('month', b.namedt, a.meetingdate), intck('month', a.meetingdate, b.nameenddt)) as dist, b.siccd
  from permno_dates_1 as a left join cusips as b
  on substr(a.cusip, 1, 8) = b.ncusip and b.namedt <= a.meetingdate <= nameenddt;
quit;

proc sort; by cusip meetingdate dist;

data permno_dates_2; set permno_dates_2; by cusip meetingdate dist;
  if first.meetingdate;

data permno_dates_2a; set permno_dates_2; 
  if dist ne .;

data permno_dates_2; set permno_dates_2; 
  if dist = .; 
  drop permno dist siccd;
run;

proc sql;
  create table permno_dates_2 as
  select a.*, b.permno, min(intck('month', b.namedt, a.meetingdate), intck('month', a.meetingdate, b.nameenddt)) as dist, b.siccd
  from permno_dates_2 as a left join cusips as b
  on substr(a.cusip, 1, 6) = substr(b.ncusip, 1, 6) and a.ticker = b.ticker and b.namedt <= a.meetingdate <= nameenddt;
quit;

data permno_dates_2b; set permno_dates_2; 
  if dist ne .;

data permno_dates_2c; set permno_dates_2; 
  if dist = .; 
  drop permno dist siccd;
run;

proc sql;
  create table permno_dates_2x as
  select a.*, b.permno, min(abs(intck('month', b.namedt, a.meetingdate)), abs(intck('month', a.meetingdate, b.nameenddt))) as dist, b.siccd
  from permno_dates_2c as a left join cusips as b
  on substr(a.cusip, 1, 8) = substr(b.ncusip, 1, 8); 
quit;

proc sort; by cusip meetingdate dist;

data permno_dates_2c; set permno_dates_2x; by cusip meetingdate dist;
  if first.meetingdate;
  if permno ne .; 
run;

data permno_dates_3; set permno_dates_2a (in=a) permno_dates_2b (in=b) permno_dates_2c (in=c);
  if a then s = 1; 
  if b then s = 2; 
  if c then s = 3; 
run;

proc sort data=comp.funda (keep=gvkey cusip conm datadate datafmt indfmt popsrc consol fyear fyr sich naicsh fic xad cik act lct epspx emp
  che at dltt lt pstkl pstk sale oibdp dp ib dvc csho dlc txditc cogs xrd pstkrv ceq txdb dcvt lt xsga prcc_f ppent xint txt capx aqc curcd) out=funda nodupkey;
  where at > 0 and sale >= 0 and 2019 >= fyear >= 2001 and indfmt= 'INDL' and datafmt= 'STD' and popsrc= 'D' and consol= 'C' and curcd = 'USD'; 
  * retrieve accounting information as early as 1960 to calculate cash flow volatility over the past 20 years;
  by gvkey fyear;
run;

proc sql;
  create table permno_dates_3 as
  select a.*, b.sich, intck('month', b.datadate, a.meetingdate) as int
  from permno_dates_3 as a left join funda as b
  on a.cusip = b.cusip and 3 <= intck('month', b.datadate, a.meetingdate) <= 18;
quit;

proc sort; by cusip meetingdate int;

data permno_dates_3; set permno_dates_3; by cusip meetingdate int;
  if first.meetingdate;
  if sich = . and siccd ne 0 then sich = siccd;
/* Select Compustat's SICH as primary SIC code, if not available, then use CRSP's historical SICCD	 */

proc sql;
  create table permno_dates_3 as
  select a.*, b.ff48, b.ff48ind
  from permno_dates_3 as a left join root.ff48 as b
  on ff1 <= sich <= ff2;
quit;

proc means n mean median p1 p99;
  var permno dist siccd sich ff48;
run;



proc sort data = permno_dates_3 out = temp.stock_meetings_contests (keep=permno meetingdate sich ff48 num_votes_nc num_votes contested20 contested5 contested10 issForMgmt iss_win mgmt_win shrd_sponsored mgmt_sponsored iss_win_nc mgmt_win_nc mgmt_lose_nc_num turnout_c) nodupkey; by permno meetingdate; 
  where num_votes > 0;
run;

proc sql;
  create table contests2 as
  select a.permno, a.meetingdate, a.sich, a.ff48, b.date, b.ret, b.prc, b.cfacshr
  from temp.stock_meetings_contests as a, crsp.dsf as b
  where a.permno = b.permno and -800 <= intck('day', b.date, a.meetingdate) <= 366+183;
quit;

proc sql;
  create table contests2 as
  select a.*, b.hml, b.smb, b.mktrf, b.umd, b.rf, a.ret-b.rf as retx, a.ret-b.rf-b.mktrf as ret_mktadj
  from contests2 as a, ff.factors_daily2020 as b
  where a.date = b.date;
quit;

proc contents data = contests2; run;

proc sort data = contests2 out = contests2a nodupkey; by permno meetingdate descending date; 
  where date < meetingdate;

data contests2a; set contests2a;
  by permno meetingdate descending date; 
  if first.meetingdate then td_count = 0;
  td_count = td_count-1; *increments in negative direction;
  retain td_count;

proc sort data = contests2 out = contests2b nodupkey; by permno meetingdate date;  
  where date >= meetingdate;

data contests2b; set contests2b;
  by permno meetingdate;
  if first.meetingdate then td_count = -1;
  td_count=td_count+1;    *increments in positive direction;
  retain td_count;

*** BETAs;
proc means data = contests2a noprint; by permno meetingdate;
  var ret; where -10-252 <= td_count < -10;
  output out = count (drop=_type_ _freq_) n = num_trdng_days_beta;
run;

proc reg data = contests2a noprint outest=mktbeta(keep=permno meetingdate intercept mktrf);
  by permno meetingdate; where -10-252 <= td_count < -10 and retx ne .;
  model retx = mktrf;

proc reg data = contests2a noprint outest=ff4beta(keep=permno meetingdate intercept mktrf smb hml umd); *;
  by permno meetingdate; where -10-252 <= td_count < -10 and retx ne .;
  model retx = mktrf smb hml umd; *;

data ff4beta; set ff4beta;
  alpha_ff4 = intercept; betam4 = mktrf; betas4 = smb; betah4 = hml; betau4 = umd;
  drop mktrf intercept;

proc reg data = contests2a noprint outest=ff3beta(keep=permno meetingdate intercept mktrf smb hml); *;
  by permno meetingdate; where -10-252 <= td_count < -10 and retx ne .;
  model retx = mktrf smb hml; *;

data ff3beta; set ff3beta;
  alpha_ff3 = intercept; betam3 = mktrf; betas3 = smb; betah3 = hml;
  drop mktrf intercept;

data stock_betas; merge mktbeta ff4beta ff3beta count; by permno meetingdate; 
  alpha_m = intercept; beta = mktrf;
  if beta ne .;
  keep permno meetingdate alpha_m beta alpha_ff3 betam3 betas3 betah3 alpha_ff4 betam4 betas4 betah4 betau4 num_trdng_days_beta; *;

proc means data = stock_betas n mean median p5 p95;

data price_pr2; set contests2a;
  if td_count = -2;
  prc_pr2 = abs(prc);
  cfacshr_pr2 = cfacshr;
  keep permno meetingdate prc_pr2 cfacshr_pr2;

proc sort; by permno meetingdate; 
run;


************************************************* Compute industry-adjusted returns *************************************************;
proc sort data=comp.funda (keep=gvkey cusip conm datadate datafmt indfmt popsrc consol fyear fyr sich naicsh fic xad cik act lct epspx emp
  che at dltt lt pstkl pstk sale oibdp dp ib dvc csho dlc txditc cogs xrd pstkrv ceq txdb dcvt lt xsga prcc_f ppent xint txt capx aqc curcd) out=cst nodupkey;
  where at > 0 and sale >= 0 and 2019 >= fyear >= 2001 and indfmt= 'INDL' and datafmt= 'STD' and popsrc= 'D' and consol= 'C' and curcd = 'USD'; 
  * retrieve accounting information as early as 1960 to calculate cash flow volatility over the past 20 years;
  by gvkey datadate;
run;

proc sql;
  create table cst as 
  select a.*, b.lpermno as permno, b.lpermco as permco, b.linktype, b.linkprim, b.liid
  from cst as a, crspcc.ccmxpf_linktable as b
  where a.gvkey = b.gvkey and linktype in ("LC", "LN", "LU", "LX", "LD", "LS") and
        usedflag in (1) and (datadate >= linkdt or linkdt = .B) and (datadate <= linkenddt or linkenddt = .E)
  order by gvkey, datadate, lpermno, lpermco, linkdt, linkenddt; 
quit; 

proc sort data = cst; by gvkey permco permno fyear descending datadate linktype descending linkprim liid;

data cst; set cst; by gvkey permco permno fyear descending datadate linktype descending linkprim liid;
  if first.fyear;
  keep gvkey permco permno fyear datadate sich naicsh;
run; 

proc sort data=crsp.stocknames(keep=permno ncusip cusip ticker namedt nameenddt shrcd exchcd siccd where=(not missing(ncusip))) 
  out=permnos nodupkey; by permno namedt nameenddt;
run;

proc sql;
  create table cst as
  select a.*, b.siccd, b.namedt, b.nameenddt
  from cst as a left join permnos as b
  on a.permno = b.permno and b.namedt <= a.datadate <= nameenddt;
quit;

proc sort data = cst nodupkey; by permno namedt nameenddt;

data cst; set cst; 
  if sich = . and siccd ne 0 then sich = siccd;
  sic2 = int(sich/100);
  sic3 = int(sich/10);
  keep gvkey permco permno namedt nameenddt sich sic2 sic3 naicsh siccd;
run; 

proc sql;
  create table cst as
  select a.*, b.ff48, b.ff48ind
  from cst as a left join root.ff48 as b
  on ff1 <= sich <= ff2;
quit;

proc sql;
  create table cst as
  select a.*, b.ff12, b.ff12ind
  from cst as a left join root.ff12 as b
  on ff1 <= sich <= ff2;
quit;

proc sql;
  create table crsp_ret as 
  select a.*, b.ret, b.date, abs(b.prc)*b.shrout as me
  from cst as a, crsp.dsf as b
  where a.permno = b.permno and a.namedt <= b.date <= a.nameenddt;
quit;

proc sort nodupkey; by permno descending date;

data crsp_ret2; set crsp_ret; by permno descending date; 
  set crsp_ret (firstobs=2 keep=permno date me rename=(permno=permno2 date=date2 me=me_lag));
  if permno ne permno2 or intck('month', date2, date) not in (0, 1) then me_lag = .;
run;

proc sort data = crsp_ret2; by ff48 date;

proc means noprint; by ff48 date;
  var ret; weight me_lag; where me_lag ne .;
  output out = returns_ff48 (drop=_type_ _freq_) mean = ret_ff48;

proc sort data = crsp_ret2; by sich date;

proc means noprint; by sich date;
  var ret; weight me_lag; where me_lag ne .;
  output out = returns_sic4 (drop=_type_ _freq_) mean = ret_sic4;

proc sort data = crsp_ret2; by sic3 date;

proc means noprint; by sic3 date;
  var ret; weight me_lag; where me_lag ne .;
  output out = returns_sic3 (drop=_type_ _freq_) mean = ret_sic3;

proc sort data = crsp_ret2; by sic2 date;

proc means noprint; by sic2 date;
  var ret; weight me_lag; where me_lag ne .;
  output out = returns_sic2 (drop=_type_ _freq_) mean = ret_sic2;
run;

************************************************* Compute industry-adjusted returns *************************************************;





data contests3; set contests2a contests2b;
  if -280 <= td_count <= 400; *****************************;

proc sql;
  create table contests3 as
  select a.*, a.ret-b.ret_ff48 as abnret_ff48
  from contests3 as a left join returns_ff48 as b
  on a.date = b.date and a.ff48 = b.ff48;
quit;

proc sql;
  create table contests3 as
  select a.*, a.ret-b.ret_sic4 as abnret_sic4
  from contests3 as a left join returns_sic4 as b
  on a.date = b.date and a.sich = b.sich;
quit;

proc sql;
  create table contests3 as
  select a.*, a.ret-b.ret_sic3 as abnret_sic3
  from contests3 as a left join returns_sic3 as b
  on a.date = b.date and int(a.sich/10) = b.sic3;
quit;

proc sql;
  create table contests3 as
  select a.*, a.ret-b.ret_sic2 as abnret_sic2
  from contests3 as a left join returns_sic2 as b
  on a.date = b.date and int(a.sich/100) = b.sic2;
quit;

proc sql;
  create table contests3 as
  select a.*, b.dgtw_xret, b.dgtw_vwret
  from contests3 as a left join temp.dgtw_returns_daily as b
  on a.permno = b.permno and a.date = b.date and b.dgtw_xret ne .;
quit;

proc sort; by permno meetingdate;

data contests3; merge contests3 stock_betas; by permno meetingdate;
  if num_trdng_days_beta >= 60 then ret_capm = ret-rf-beta*mktrf; 
  if num_trdng_days_beta >= 60 then retff3 = ret-rf-betam3*mktrf-betah3*hml-betas3*smb; 
  if num_trdng_days_beta >= 60 then retff4 = ret-rf-betam4*mktrf-betah4*hml-betas4*smb-betau4*umd; 
  abs_ret_mktadj = abs(ret_mktadj);
  abs_retff4 = abs(retff4);
  abs_dgtw_xret = abs(dgtw_xret);

proc means data = contests3 n mean median p25 p75;
run;

proc sort data = contests3 nodupkey; by permno meetingdate date; run;

proc means data = contests3 noprint; by permno meetingdate;
  var retx ret_capm retff3 retff4 ret_mktadj dgtw_xret; where td_count = 0;
  output out = car1d sum = car1d car1d_capm car1d_ff3 car1d_ff4 car1d_m car1d_dgtw;

proc means data = contests3 noprint; by permno meetingdate;
  var retx ret_capm retff3 retff4 ret_mktadj dgtw_xret; where -1 <= td_count <= 0;
  output out = car2d sum = car2d car2d_capm car2d_ff3 car2d_ff4 car2d_m car2d_dgtw;

proc means data = contests3 noprint; by permno meetingdate;
  var retx ret_capm retff3 retff4 ret_mktadj dgtw_xret abs_ret_mktadj abs_retff4 abs_dgtw_xret; where -1 <= td_count <= 1;
  output out = car3d sum = car3d car3d_capm car3d_ff3 car3d_ff4 car3d_m car3d_dgtw abs_car3d_m abs_car3d_ff4 abs_car3d_dgtw;

proc means data = contests3 noprint; by permno meetingdate;
  var retx ret_capm retff3 retff4 ret_mktadj dgtw_xret; where 1 <= td_count <= 5;
  output out = car5d sum = car5d car5d_capm car5d_ff3 car5d_ff4 car5d_m car5d_dgtw;

proc means data = contests3 noprint; by permno meetingdate;
  var retx ret_capm retff3 retff4 ret_mktadj dgtw_xret; where 0 <= td_count <= 5;
  output out = car6d sum = car6d car6d_capm car6d_ff3 car6d_ff4 car6d_m car6d_dgtw;

proc means data = contests3 noprint; by permno meetingdate;
  var retx ret_capm retff3 retff4 ret_mktadj dgtw_xret; where -1 <= td_count <= 5;
  output out = car7d sum = car7d car7d_capm car7d_ff3 car7d_ff4 car7d_m  car7d_dgtw;

proc means data = contests3 noprint; by permno meetingdate;
  var retx ret_capm retff3 retff4 ret_mktadj dgtw_xret; where 1 <= td_count <= 10;
  output out = car10d sum = car10d car10d_capm car10d_ff3 car10d_ff4 car10d_m car10d_dgtw;

proc means data = contests3 noprint; by permno meetingdate;
  var retx ret_capm retff3 retff4 ret_mktadj dgtw_xret; where 0 <= td_count <= 10;
  output out = car11d sum = car11d car11d_capm car11d_ff3 car11d_ff4 car11d_m car11d_dgtw;

proc means data = contests3 noprint; by permno meetingdate num_trdng_days_beta;
  var retx ret_capm retff3 retff4 ret_mktadj dgtw_xret abs_ret_mktadj abs_retff4 abs_dgtw_xret abnret_ff48 abnret_sic4 abnret_sic3 abnret_sic2; where -1 <= td_count <= 10;
  output out = car12d sum = car12d car12d_capm car12d_ff3 car12d_ff4 car12d_m car12d_dgtw abs_car12d_m abs_car12d_ff4 abs_car12d_dgtw car12d_ff48 car12d_sic4 car12d_sic3 car12d_sic2 min(date) = st_date12 max(date)=end_date12;

proc means data = contests3 noprint; by permno meetingdate;
  var retx ret_capm retff3 retff4 ret_mktadj dgtw_xret; where 1 <= td_count <= 21;
  output out = car21d sum = car21d car21d_capm car21d_ff3 car21d_ff4 car21d_m car21d_dgtw;

proc means data = contests3 noprint; by permno meetingdate num_trdng_days_beta;
  var retx ret_capm retff3 retff4 ret_mktadj dgtw_xret; where -1 <= td_count <= 21;
  output out = car22d sum = car22d car22d_capm car22d_ff3 car22d_ff4 car22d_m car22d_dgtw;

proc means data = contests3 noprint; by permno meetingdate num_trdng_days_beta;
  var retx ret_capm retff3 retff4 ret_mktadj dgtw_xret abs_ret_mktadj abs_retff4 abs_dgtw_xret; where 1 <= td_count <= 63;
  output out = car63d sum = car63d car63d_capm car63d_ff3 car63d_ff4 car63d_m car63d_dgtw abs_car63d_m abs_car63d_ff4 abs_car63d_dgtw n(retx) = num_63d;

proc means data = contests3 noprint; by permno meetingdate num_trdng_days_beta;
  var retx ret_capm retff3 retff4 ret_mktadj dgtw_xret abs_ret_mktadj abs_retff4 abs_dgtw_xret; where 1 <= td_count <= 126;
  output out = car126d sum = car126d car126d_capm car126d_ff3 car126d_ff4 car126d_m car126d_dgtw abs_car126d_m abs_car126d_ff4 abs_car126d_dgtw; 

proc means data = contests3 noprint; by permno meetingdate num_trdng_days_beta;
  var retx ret_capm retff3 retff4 ret_mktadj dgtw_xret; where 1 <= td_count <= 252;
  output out = car252d sum = car252d car252d_capm car252d_ff3 car252d_ff4 car252d_m car252d_dgtw;

proc means data = contests3 noprint; by permno meetingdate num_trdng_days_beta;
  var retx ret_capm retff3 retff4 ret_mktadj dgtw_xret; where 1 <= td_count <= 378;
  output out = car378d sum = car378d car378d_capm car378d_ff3 car378d_ff4 car378d_m car378d_dgtw;

proc means data = contests3 noprint; by permno meetingdate num_trdng_days_beta;
  var retx ret_capm retff3 retff4 ret_mktadj dgtw_xret; where -11 <= td_count < -1;
  output out = car_pr10d sum = car_pr10d car_pr10d_capm car_pr10d_ff3 car_pr10d_ff4 car_pr10d_m car_pr10d_dgtw;

proc means data = contests3 noprint; by permno meetingdate num_trdng_days_beta;
  var retx ret_mktadj; where -252-1 <= td_count < -1;
  output out = car_pr252d sum = car_pr252d car_pr252d_m;

proc means data = contests3 noprint; by permno meetingdate num_trdng_days_beta;
  var retx ret_mktadj; where -252-11 <= td_count < -11;
  output out = car_pr11_252d sum = car_pr11_252d car_pr11_pr252d_m;

data temp.contests_car_permno; merge price_pr2 car12d car1d car2d car3d car5d car6d car7d car10d car11d car12d car21d car22d car63d car126d car252d car378d car_pr10d car_pr252d car_pr11_252d; by permno meetingdate;
  format meetingdate st_date12 end_date12 date9.;
  drop _type_ _freq_;
run;

**** proxy contest returns;


data returns; set temp.meetings_car_permno temp.contests_car_permno;

proc sort nodupkey; by permno meetingdate; run;

proc sql;
  create table test as
  select a.*, b.*
  from test as a left join returns 
    (keep=permno meetingdate prc_pr2 cfacshr_pr2 car12d_m ) as b
  on a.permno = b.permno and year(a.meetingdate) = year(b.meetingdate) and month(a.meetingdate) = month(b.meetingdate) and day(a.meetingdate) = day(b.meetingdate); * intck('day', a.meetingdate, b.meetingdate) = 0;
quit;

data test; set test;
  if cfacshr_rdate/cfacshr_pr2 > 0 then market_value_pr2 = prc_pr2*nbr_shares*(cfacshr_rdate/cfacshr_pr2);
  if market_value_pr2 > 0;

proc sort data = test nodupkey; by year permno meetingdate wficn crsp_cl_grp itemonagendaid; 

data test; set test; by year permno meetingdate;
  if WinVote = 1 then car12d_m_win = car12d_m;
  if WinVote = 0 then car12d_m_win = -car12d_m;

proc sort data = test; by wficn crsp_cl_grp year permno meetingdate;

proc means data = test noprint; by wficn crsp_cl_grp year permno meetingdate;
  var WinVote;
  output out = num (drop=_type_ _freq_) n = number_votes;

data test2; merge test num; by wficn crsp_cl_grp year permno meetingdate;
  market_value_adj = market_value_pr2/number_votes;
  pwt_adj = pwt/number_votes;
  wt_adj = wt/number_votes;
run;
**** End of retrieving for each fund-proposal, the past votes and returns;

proc sort data = test out = unique (keep=wficn crsp_cl_grp mend exchcd shrcd) nodupkey; by wficn crsp_cl_grp mend; 

proc sql;
  create table reg as
  select a.wficn, a.crsp_cl_grp, a.mend, b.permno, b.meetingdate, b.itemonagendaid, b.issForMgmt, b.car12d_m, b.car12d_m_win, b.WinVote, b.margin, b.mgmt_win, b.market_value_pr2, b.market_value_adj, b.pwt, b.pwt_adj
  from unique as a, test2 as b
  where a.wficn = b.wficn and a.crsp_cl_grp = b.crsp_cl_grp and 1 <= intck('month', b.meetingdate, a.mend) <= 12;
quit; 

proc sort data = reg; by wficn crsp_cl_grp mend; where market_value_adj ne .;

proc means data = reg noprint; by wficn crsp_cl_grp mend;
  where car12d_m ne .; 
  var WinVote;
  output out = count2 (drop=_type_ _freq_) n = num_votes;

proc means data = reg noprint; by wficn crsp_cl_grp mend;
  var car12d_m_win; weight market_value_adj; 
  output out = win_ret_1 (drop=_type_ _freq_) mean = vote_alpha;

data measure; merge count2 win_ret_1; by wficn crsp_cl_grp mend; 

proc sort data = temp.fundinfo nodupkey out = fundinfo; by wficn crsp_cl_grp caldt; where mtna ne .; 

proc sql;
  create table measure as
  select a.*, b.caldt, b.crsp_obj_cd2, b.mtna, b.mtna_adj, b.pct_common_eq
  from measure as a left join fundinfo as b
  on a.wficn = b.wficn and a.crsp_cl_grp = b.crsp_cl_grp and 1 <= intck('month', b.caldt, a.mend) <= 6;
quit;

proc sort; by wficn crsp_cl_grp mend caldt; 

data measure; set measure; by wficn crsp_cl_grp mend caldt; 
  if last.mend;
  if (index(crsp_obj_cd2, 'ED') = 1) and mtna >= 5 and num_votes > 10; 

proc sort; by mend;

proc rank data = measure out  = measure groups = 5; by mend;
  var vote_alpha ;
  ranks q_vote_alpha;
run;

proc sort data = measure; by wficn crsp_cl_grp mend; 

data proposals_incl_contests2; merge proposals_incl_contests measure; by wficn crsp_cl_grp mend;

  if issForMgmt = 1 then iss_win = mgmt_win;
  if issForMgmt = 0 then iss_win = -mgmt_win;
  month = month(meetingdate);
  yyyymm = year(meetingdate)*100+month;
  if wt ne .;
  margin = .;
run;

proc sort data = proposals_incl_contests2 nodupkey; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid issForMgmt issue margin year wficn crsp_cl_grp; 

proc means data = proposals_incl_contests2 noprint; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid issForMgmt issue margin year;
  var wt; 
  output out = count3 (drop=_type_ _freq_) sum = mfo n = num_mf;

proc sort; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid issForMgmt issue margin year;

proc means data = proposals_incl_contests2 noprint; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid issForMgmt issue margin year;
  var wt; where q_vote_alpha in (4) and WinVote = 1; 
  output out = win_ret_2a (drop=_type_ _freq_) sum = wt_win_inf;

proc means data = proposals_incl_contests2 noprint; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid issForMgmt issue margin year;
  var wt; where q_vote_alpha in (4) and WinVote = 0; 
  output out = win_ret_2b (drop=_type_ _freq_) sum = wt_lose_inf;

proc means data = proposals_incl_contests2 noprint; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid issForMgmt issue margin year;
  var wt; where 0 <= q_vote_alpha <= 3 and WinVote = 1; 
  output out = win_ret_2c (drop=_type_ _freq_) sum = wt_win_other;

proc means data = proposals_incl_contests2 noprint; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid issForMgmt issue margin year;
  var wt; where 0 <= q_vote_alpha <= 3 and WinVote = 0; 
  output out = win_ret_2d (drop=_type_ _freq_) sum = wt_lose_other;

data proposals_incl_contests3; merge count3 win_ret_2a win_ret_2b win_ret_2c win_ret_2d; 
    by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid issForMgmt issue margin year;
  if wt_win_inf = . then wt_win_inf = 0;
  if wt_lose_inf = . then wt_lose_inf = 0;
  net_win_informed = (wt_win_inf-wt_lose_inf); 

  if wt_win_other = . then wt_win_other = 0;
  if wt_lose_other = . then wt_lose_other = 0;
  net_win_uninformed = (wt_win_other-wt_lose_other); 

  if issformgmt = 1 then iss_win = mgmt_win; else if issformgmt = 0 then iss_win = 1-mgmt_win;

  frac_informed = (wt_win_inf+wt_lose_inf)/mfo;

  if num_mf >= 1;

proc sql;
  create table proposals_incl_contests4 as 
  select *
  from proposals_incl_contests3 as a left join temp.cst_matched as b
  on a.permno = b.permno and intck('day', a.meetingdate, b.meetingdate) = 0;
quit; run; * temp.cst_matched is from 06CST_CRSP_Meetings.sas;

proc sort data = proposals_incl_contests4 nodupkey; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid;
run;

proc sql;
  create table proposals_incl_contests4 as
  select a.*, b.*
  from proposals_incl_contests4 as a left join returns as b
  on a.permno = b.permno and intck('day', a.meetingdate, b.meetingdate) = 0;
quit;

proc sort data = proposals_incl_contests4; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid issForMgmt issue margin year;

data proposals_incl_contests4; set proposals_incl_contests4; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid issForMgmt issue margin year;
  if last.year;
run;

*** Fraction of contentious votes in the past 12 months;
data stock_meetings; set temp.stock_meetings temp.stock_meetings_contests; 

proc sort nodupkey; by permno meetingdate; run;

proc sql;
  create table proposal_count as
  select a.permno, a.meetingdate, b.num_votes, b.contested20
  from proposals_incl_contests4 as a left join stock_meetings as b
  on a.permno = b.permno and 1 <= intck('month', b.meetingdate, a.meetingdate) <= 12;
quit; * temp.stock_meetings is from 05Meetings_CAR.sas;

proc sort; by permno meetingdate ;

proc means noprint; by permno meetingdate;
  var num_votes contested20;
  output out = proposal_count (drop=_type_ _freq_) sum = num_votes contested20;
run;

proc sql;
  create table proposals_incl_contests4 as 
  select a.*, b.contested20 as n_contested, b.contested20/b.num_votes as frac_contested
  from proposals_incl_contests4 as a left join proposal_count as b
  on a.permno = b.permno and a.meetingdate = b.meetingdate;
quit;

proc sql;
  create table proposals_incl_contests5 as 
  select a.*, b.issForMgmt as issForMgmt_meeting, b.mgmt_win_nc, b.mgmt_lose_nc_num
  from proposals_incl_contests4 as a left join stock_meetings as b
  on a.permno = b.permno and year(a.meetingdate) = year(b.meetingdate) and month(a.meetingdate) = month(b.meetingdate) and day(a.meetingdate) = day(b.meetingdate);
quit;

proc sort data = proposals_incl_contests5; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid issForMgmt issue margin year;

data proposals_incl_contests5; set proposals_incl_contests5; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid issForMgmt issue margin year;
  if last.year;
  if ind = . then ind = 48;
  if 0 <= mgmt_win_nc < 1 then mgmt_lost_nc = 1; else mgmt_lost_nc = 0;
  if n_contested = . then n_contested = 0;
  ind_year = ind*10000+year;
  log_nanalyst = log(1+nanalyst);

%winsor(dsetin=proposals_incl_contests5, dsetout=proposals_incl_contests5, byvar=none, vars=net_win_informed net_win_uninformed size mb leverage_b num_busseg capex sp500 roa mfo io io_hhi, type=winsor, pctl=1 99); 

proc sort data=proposals_incl_contests5 out = temp.proposals_incl_contests nodupkey; by permno meetingdate itemonagendaid;
   where car63d_dgtw ~= . and iss_win ne . and mb ne . and leverage_b ne . and car63d_ff4 ne . and net_win_informed ne . and net_win_uninformed ne . and mgmt_win ne . and 
     iss_win ne . and size ne . and mb ne . and car_pr252d_m ne . and leverage_b ne . and capex ne . and sp500 ne . and mfo ne . and log_nanalyst ne .; 
run;


proc export data= temp.proposals_incl_contests 
            outfile= "D:\Dropbox\InformedVoting\proposals_incl_contests.dta" 
            dbms=stata replace;
run;



* Blanket recommendations: ISS recommends voting for a proposal type at least 95% of the time or recommends voting against at least 95% of the time in the past 12 months;
data temp; set temp.iss_votes_ret;
  if 0 < abs(margin) <= .20 and issue ne '';

proc sort data = temp nodupkey out = proposals (keep=year mend exchcd shrcd rqdate wficn crsp_cl_grp winvote wt permno meetingdate mgmt_sponsored mgmt_win margin agendaGeneralDesc Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue pwt voterequirement); 
  by wficn crsp_cl_grp mend permno meetingdate wt itemonagendaid; 

proc sort data = proposals out = unique_permno (keep=permno mend exchcd shrcd) nodupkey; by permno mend; 

proc sort data = proposals out = unique_proposals (keep=permno meetingdate mgmt_sponsored itemonagendaid issForMgmt) nodupkey; by permno meetingdate itemonagendaid; 

proc freq data = unique_proposals; tables mgmt_sponsored issForMgmt; run;

proc sort data = proposals out = unique (keep=wficn crsp_cl_grp mend exchcd shrcd) nodupkey; by wficn crsp_cl_grp mend; 

data unique; set unique;
  if month(mend) in (9,10,11,12) then mend2 = mdy(6, 30, year(mend));
  if 1 <= month(mend) <= 8 then mend2 = mdy(6, 30, year(mend)-1);
  format mend2 date9.;

proc sql;
  create table reg as
  select a.wficn, a.crsp_cl_grp, a.mend, b.permno, b.meetingdate, b.itemonagendaid, b.issForMgmt, b.iss_conform, 
    b.car12d_m_win, b.car12d_m, b.car7d_m, b.car7d_m_win, b.car5d_m, b.car5d_m_win, 
    b.WinVote, b.margin, b.mgmt_win, b.market_value_pr2, b.market_value_adj, b.pwt, b.pwt_adj
  from unique as a, test1 as b
  where a.wficn = b.wficn and a.crsp_cl_grp = b.crsp_cl_grp and 1 <= intck('month', b.meetingdate, a.mend) <= 12; 
quit; * test1 is from 09Tests_fund_level.sas;

proc sort data = reg; by wficn crsp_cl_grp mend; where market_value_adj ne .;

proc means data = reg noprint; by wficn crsp_cl_grp mend;
  where car12d_m ne .; 
  var WinVote;
  output out = count2 (drop=_type_ _freq_) n = num_votes mean(iss_conform) = iss_conform;

proc means data = reg noprint; by wficn crsp_cl_grp mend;
  var car12d_m_win; weight market_value_adj; 
  output out = win_ret_1a (drop=_type_ _freq_) 
  mean = vote_alpha ;

proc means data = reg noprint; by wficn crsp_cl_grp mend; 
  var car12d_m_win; 
  output out = win_ret_1b (drop=_type_ _freq_) mean = vote_alpha_ew;

data measure; merge count2 win_ret_1a win_ret_1b; by wficn crsp_cl_grp mend;
run;

*** Vote with ISS in the past;
data all_proposals; set temp.iss_votes_ret;
  if issForMgmt = 1 then iss_win = mgmt_win;
  if issForMgmt = 0 then iss_win = -mgmt_win;
  month = month(meetingdate);
  yyyymm = year(meetingdate)*100+month;
  if issue ne '';
  keep wficn crsp_cl_grp year permno meetingdate issue issAgendaItemId itemonagendaid margin voteAgainstMgmt iss_conform issForMgmt mgmt_win nbr_shares cfacshr_rdate WinVote fundfor issfor;

proc sql;
  create table all_proposals as
  select a.*, b.*
  from all_proposals as a, temp.meetings_car_permno 
    (keep=permno meetingdate prc_pr2 cfacshr_pr2) as b
  where a.permno = b.permno and year(a.meetingdate) = year(b.meetingdate) and month(a.meetingdate) = month(b.meetingdate) and day(a.meetingdate) = day(b.meetingdate) and prc_pr2*nbr_shares*(cfacshr_rdate/cfacshr_pr2) > 0; 
quit;

data all_proposals; set all_proposals;
  if cfacshr_pr2 > 0 then market_value_pr2 = prc_pr2*nbr_shares*(cfacshr_rdate/cfacshr_pr2);
  if market_value_pr2 > 0;

proc sql;
  create table all_proposals as
  select a.wficn, a.crsp_cl_grp, a.mend, b.permno, b.issAgendaItemId, b.iss_conform, b.margin, b.issfor, b.fundfor
  from unique as a, all_proposals as b
  where a.wficn = b.wficn and a.crsp_cl_grp = b.crsp_cl_grp and 1 <= intck('month', b.meetingdate, a.mend) <= 12; 
quit; 

proc sort data = all_proposals; by wficn crsp_cl_grp mend; 

proc means data = all_proposals noprint; by wficn crsp_cl_grp mend;
  var iss_conform;
  output out = temp.iss_conform (drop=_type_ _freq_) mean = iss_conform;
run;

%dummy(data=all_proposals, out=all_proposals, var=issAgendaItemId, prefix=p); 

proc reg data=all_proposals outest=outest noprint; by wficn crsp_cl_grp mend;
  model fundfor = issfor p1-p141 / rsquare press sse adjrsq;
run;
quit;

data temp.outest_r2; set outest; by wficn crsp_cl_grp mend; *coeff1;
 r2 = _rsq_;
 nobs = _P_ + _EDF_;
keep wficn crsp_cl_grp mend r2 nobs;
run;




data measure1; merge measure (in=a) temp.iss_conform temp.outest_r2; by wficn crsp_cl_grp mend; 
  if a;

proc sort data = temp.fundinfo nodupkey out = fundinfo; by wficn crsp_cl_grp caldt; where mtna ne .; 

proc sql;
  create table measure1 as
  select a.*, b.caldt, b.crsp_obj_cd2, b.mtna, b.mtna_adj, b.pct_common_eq, b.mgmt_no2
  from measure1 as a left join fundinfo as b
  on a.wficn = b.wficn and a.crsp_cl_grp = b.crsp_cl_grp and 1 <= intck('month', b.caldt, a.mend) <= 6;
quit;

proc sort; by wficn crsp_cl_grp mend caldt; 

data measure1; set measure1; by wficn crsp_cl_grp mend caldt; 
  if last.mend;
  if (index(crsp_obj_cd2, 'ED') = 1) and mtna >= 5 and num_votes > 10; 
  inverse_r2 = 1/r2;
  format mend date9.;

proc sql;
  create table measure1 as
  select a.*, b.num_ips_proxy_scaled, b.num_ips_proxy_ind
  from measure1 as a left join temp.mgmt_co_level as b
  on a.mgmt_no2 = b.mgmt_no2 and year(a.mend) = b.year+1;
quit;

proc means data = measure1 n mean median min max p1 p5 p10 p25 p75 p90 p95 p99 std; 
  var vote_alpha iss_conform nobs inverse_r2 r2 num_ips_proxy_scaled num_ips_proxy_ind;
run;

proc sort data = measure1; by mend;

proc rank data = measure1 out = measure1 groups = 5; by mend; 
  var vote_alpha vote_alpha_ew iss_conform inverse_r2 num_ips_proxy_scaled;
  ranks q_vote_alpha q_vote_alpha_ew q_iss_conform q_inverse_r2 q_num_ips; 
run;

proc sort data = measure1; by wficn crsp_cl_grp mend; 

data proposals2; merge proposals measure1; by wficn crsp_cl_grp mend;
  wt_car12d_ff4_diff = wt*car12d_ff4_diff;
  if wt ne .;

data temp.proposal_funds; set proposals2; 
run;


proc sort data = proposals2 nodupkey; by permno meetingdate mgmt_sponsored mgmt_win agendaGeneralDesc Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year wficn crsp_cl_grp; 

proc means data = proposals2 noprint; by permno meetingdate mgmt_sponsored mgmt_win agendaGeneralDesc Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year;
  var wt; 
  output out = count3 (drop=_type_ _freq_) sum = mfo n = num_mf;

proc sort; by permno meetingdate mgmt_sponsored mgmt_win agendaGeneralDesc Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year;

proc means data = proposals2 noprint; by permno meetingdate mgmt_sponsored mgmt_win agendaGeneralDesc Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year;
  var wt; where q_vote_alpha in (4) and WinVote = 1; 
  output out = win_ret_2a (drop=_type_ _freq_) sum = wt_win_inf;

proc means data = proposals2 noprint; by permno meetingdate mgmt_sponsored mgmt_win agendaGeneralDesc Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year;
  var wt; where q_vote_alpha in (4) and WinVote = 0; 
  output out = win_ret_2b (drop=_type_ _freq_) sum = wt_lose_inf;

proc means data = proposals2 noprint; by permno meetingdate mgmt_sponsored mgmt_win agendaGeneralDesc Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year;
  var wt; where 0 <= q_vote_alpha <= 3 and WinVote = 1; 
  output out = win_ret_2c (drop=_type_ _freq_) sum = wt_win_other;

proc means data = proposals2 noprint; by permno meetingdate mgmt_sponsored mgmt_win agendaGeneralDesc Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year;
  var wt; where 0 <= q_vote_alpha <= 3 and WinVote = 0; 
  output out = win_ret_2d (drop=_type_ _freq_) sum = wt_lose_other;

proc means data = proposals2 noprint; by permno meetingdate mgmt_sponsored mgmt_win agendaGeneralDesc Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year;
  var wt; where q_vote_alpha in (0) and WinVote = 1; 
  output out = win_ret_2e (drop=_type_ _freq_) sum = wt_win_btmQ;

proc means data = proposals2 noprint; by permno meetingdate mgmt_sponsored mgmt_win agendaGeneralDesc Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year;
  var wt; where q_vote_alpha in (0) and WinVote = 0; 
  output out = win_ret_2f (drop=_type_ _freq_) sum = wt_lose_btmQ;

proc means data = proposals2 noprint; by permno meetingdate mgmt_sponsored mgmt_win agendaGeneralDesc Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year;
  var wt; where q_vote_alpha in (1,2,3) and WinVote = 1; 
  output out = win_ret_2g (drop=_type_ _freq_) sum = wt_win_mid;

proc means data = proposals2 noprint; by permno meetingdate mgmt_sponsored mgmt_win agendaGeneralDesc Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year;
  var wt; where q_vote_alpha in (1,2,3) and WinVote = 0; 
  output out = win_ret_2h (drop=_type_ _freq_) sum = wt_lose_mid;

proc means data = proposals2 noprint; by permno meetingdate mgmt_sponsored mgmt_win agendaGeneralDesc Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year;
  var wt; where q_vote_alpha_ew in (4) and WinVote = 1; 
  output out = win_ret_2i (drop=_type_ _freq_) sum = wt_win_inf_ew;

proc means data = proposals2 noprint; by permno meetingdate mgmt_sponsored mgmt_win agendaGeneralDesc Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year;
  var wt; where q_vote_alpha_ew in (4) and WinVote = 0; 
  output out = win_ret_2j (drop=_type_ _freq_) sum = wt_lose_inf_ew;

proc means data = proposals2 noprint; by permno meetingdate mgmt_sponsored mgmt_win agendaGeneralDesc Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year;
  var wt; where 0 <= q_vote_alpha_ew <= 3 and WinVote = 1; 
  output out = win_ret_2k (drop=_type_ _freq_) sum = wt_win_other_ew;

proc means data = proposals2 noprint; by permno meetingdate mgmt_sponsored mgmt_win agendaGeneralDesc Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year;
  var wt; where 0 <= q_vote_alpha_ew <= 3 and WinVote = 0; 
  output out = win_ret_2l (drop=_type_ _freq_) sum = wt_lose_other_ew;

proc means data = proposals2 noprint; by permno meetingdate mgmt_sponsored mgmt_win agendaGeneralDesc Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year;
  var wt; where q_iss_conform in (0) and WinVote = 1; 
  output out = win_ret_2m (drop=_type_ _freq_) sum = wt_win_active;

proc means data = proposals2 noprint; by permno meetingdate mgmt_sponsored mgmt_win agendaGeneralDesc Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year;
  var wt; where q_iss_conform in (0) and WinVote = 0; 
  output out = win_ret_2n (drop=_type_ _freq_) sum = wt_lose_active;

proc means data = proposals2 noprint; by permno meetingdate mgmt_sponsored mgmt_win agendaGeneralDesc Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year;
  var wt; where q_iss_conform not in (0) and WinVote = 1; 
  output out = win_ret_2o (drop=_type_ _freq_) sum = wt_win_passive;

proc means data = proposals2 noprint; by permno meetingdate mgmt_sponsored mgmt_win agendaGeneralDesc Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year;
  var wt; where q_iss_conform not in (0) and WinVote = 0; 
  output out = win_ret_2p (drop=_type_ _freq_) sum = wt_lose_passive;

proc means data = proposals2 noprint; by permno meetingdate mgmt_sponsored mgmt_win agendaGeneralDesc Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year;
  var wt; where num_ips_proxy_ind in (1) and WinVote = 1; 
  output out = win_ret_2q (drop=_type_ _freq_) sum = wt_win_high_num_ips;

proc means data = proposals2 noprint; by permno meetingdate mgmt_sponsored mgmt_win agendaGeneralDesc Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year;
  var wt; where num_ips_proxy_ind in (1) and WinVote = 0; 
  output out = win_ret_2r (drop=_type_ _freq_) sum = wt_lose_high_num_ips;

proc means data = proposals2 noprint; by permno meetingdate mgmt_sponsored mgmt_win agendaGeneralDesc Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year;
  var wt; where num_ips_proxy_ind ne .; 
  output out = win_ret_2s (drop=_type_ _freq_) sum = num_ips_ind;

data proposals3; merge count3 win_ret_2a win_ret_2b win_ret_2c win_ret_2d win_ret_2e win_ret_2f win_ret_2g win_ret_2h  
  win_ret_2i win_ret_2j win_ret_2k win_ret_2l win_ret_2m win_ret_2n win_ret_2o win_ret_2p win_ret_2q win_ret_2r win_ret_2s; 
    by permno meetingdate mgmt_sponsored mgmt_win agendaGeneralDesc Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year;
  if wt_win_inf = . then wt_win_inf = 0;
  if wt_lose_inf = . then wt_lose_inf = 0;
  net_win_informed = (wt_win_inf-wt_lose_inf);
  if wt_win_inf+wt_lose_inf > 0 then agree_informed = abs(wt_win_inf-wt_lose_inf)/(wt_win_inf+wt_lose_inf);

  if wt_win_other = . then wt_win_other = 0;
  if wt_lose_other = . then wt_lose_other = 0;
  net_win_uninformed = (wt_win_other-wt_lose_other);
  if wt_win_other+wt_lose_other > 0 then agree_uninformed = abs(wt_win_other-wt_lose_other)/(wt_win_other+wt_lose_other);

  if wt_win_btmQ = . then wt_win_btmQ = 0;
  if wt_lose_btmQ = . then wt_lose_btmQ = 0;
  net_win_btmQ = (wt_win_btmQ-wt_lose_btmQ);
  if wt_win_btmQ+wt_lose_btmQ > 0 then agree_btmQ = abs(wt_win_btmQ-wt_lose_btmQ)/(wt_win_btmQ+wt_lose_btmQ);

  if wt_win_mid = . then wt_win_mid = 0;
  if wt_lose_mid = . then wt_lose_mid = 0;
  net_win_mid = (wt_win_mid-wt_lose_mid);

  if wt_win_inf_ew = . then wt_win_inf_ew = 0;
  if wt_lose_inf_ew = . then wt_lose_inf_ew = 0;
  net_win_informed_ew = (wt_win_inf_ew-wt_lose_inf_ew);

  if wt_win_other_ew = . then wt_win_other_ew = 0;
  if wt_lose_other_ew = . then wt_lose_other_ew = 0;
  net_win_uninformed_ew = (wt_win_other_ew-wt_lose_other_ew);

  if wt_win_active = . then wt_win_active = 0;
  if wt_lose_active = . then wt_lose_active = 0;
  net_win_active = (wt_win_active-wt_lose_active);

  if wt_win_passive = . then wt_win_passive = 0;
  if wt_lose_passive = . then wt_lose_passive = 0;
  net_win_passive = (wt_win_passive-wt_lose_passive);

  if wt_win_high_num_ips = . and num_ips_ind > 0 then wt_win_high_num_ips = 0;
  if wt_lose_high_num_ips = . and num_ips_ind > 0 then wt_lose_high_num_ips = 0;
  net_win_high_num_ips = (wt_win_high_num_ips-wt_lose_high_num_ips);

  if issformgmt = 1 then iss_win = mgmt_win; else if issformgmt = 0 then iss_win = 1-mgmt_win;
  if num_mf >= 1; 
run;

proc sql;
  create table proposals4 as 
  select *
  from proposals3 as a left join temp.cst_matched as b
  on a.permno = b.permno and intck('day', a.meetingdate, b.meetingdate) = 0;
quit; run; * temp.cst_matched is from 06CST_CRSP_Meetings.sas;

proc sort data = proposals4 nodupkey; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid;
run;

proc sql;
  create table proposals4 as
  select a.*, b.*
  from proposals4 as a left join temp.meetings_car_permno as b
  on a.permno = b.permno and intck('day', a.meetingdate, b.meetingdate) = 0;
quit;

proc sort data = proposals4; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year;

data proposals4; set proposals4; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year;
  if last.year;
run;

* Use agenda item description (�ItemDesc�) to classify proposals into finer groups: ISSAgendaItemID2; 
proc sort data = drop.Proposal_types; by ISSAgendaItemID agendaGeneralDesc itemDesc descending num_proposals;

data Proposal_types; set drop.Proposal_types; by ISSAgendaItemID agendaGeneralDesc itemDesc;
  if first.itemDesc; run;

proc sql;
  create table proposals4b as
  select a.*, b.ISSAgendaItemID2
  from proposals4 as a left join Proposal_types as b
  on a.issAgendaItemId = b.issAgendaItemId and a.agendaGeneralDesc = b.agendaGeneralDesc and a.itemDesc = b.itemDesc;
quit; 

proc sql;
  create table proposals4b as 
  select a.*, b.issForMgmt as issForMgmt_meeting, b.shrd_sponsored as num_shrd_sponsored, b.mgmt_sponsored as num_mgmt_sponsored, b.iss_win_nc, b.mgmt_win_nc, b.num_votes_nc, b.mgmt_lose_nc_num, b.turnout_c
  from proposals4b as a left join temp.stock_meetings as b
  on a.permno = b.permno and year(a.meetingdate) = year(b.meetingdate) and month(a.meetingdate) = month(b.meetingdate) and day(a.meetingdate) = day(b.meetingdate);
quit;

*** Blanket recommendations on the same type of contentious proposals in the past 12 months;
* Use issAgendaItemId provided by ISS;
data permno_dates; set permno_dates;
  if issrec in ("For") then issFor = 1; else if issrec ne '' then issFor = 0;
  if issrec in ("Against") then issAgainst = 1; else if issrec ne '' then issAgainst = 0; * permno_dates is from 05Meeting_CAR.sas;

proc sql;
  create table proposal_types as
  select a.issAgendaItemId, a.meetingdate, b.issfor, b.issAgainst, b.companyid, b.meetingdate as meetingdate2
  from proposals4 as a left join permno_dates as b
  on a.issAgendaItemId = b.issAgendaItemId and 1 <= intck('month', b.meetingdate, a.meetingdate) <= 12;
quit;

proc sort nodupkey; by issAgendaItemId meetingdate companyid meetingdate2; 
run;

proc means noprint; by issAgendaItemId meetingdate;
  var issFor issAgainst;
  output out = blanket (drop=_type_ _freq_) n = num_type mean = issFor issAgainst;

data blanket; set blanket;
  if num_type > 1;
  if issagainst >= 0.95 or issfor >= .95 then blanket = 1;
run;

proc sql;
  create table proposals4b as 
  select a.*, b.blanket
  from proposals4b as a left join blanket as b
  on a.issAgendaItemId = b.issAgendaItemId and a.meetingdate = b.meetingdate;
quit; 


* Use itemDesc to partition proposal types into finer categories;
data item_dates; set iss.Vote_Results2003_2018;
  if VoteRequirement = 66.67 then VoteRequirement = .66;
  if VoteRequirement = .01 and ISSAgendaItemID not in ('M0201', 'M0299', 'S0299') then VoteRequirement = .5; *fix data errors;
  if votedfor+votedagainst <= 1 then delete; *likely data errors;

  if base in ('F+A', 'F A') then margin = votedfor/(votedfor+votedagainst)-voterequirement;
  if base in ('F+A+AB', 'F A AB') then margin = votedfor/(votedfor+votedagainst+votedabstain)-voterequirement;
  if base = 'Outstanding' then margin = votedfor/outstandingshare-voterequirement;
  if . < abs(margin) <= .2 then contested20 = 1; else if margin ne . then contested20 = 0;
  if . < abs(margin) <= .1 then contested10 = 1; else if margin ne . then contested10 = 0;
  if . < abs(margin) <= .05 then contested5 = 1; else if margin ne . then contested5 = 0;

  if issrec in ("For") then issFor = 1; else if issrec ne '' then issFor = 0;
  if issrec in ("Against") then issAgainst = 1; else if issrec ne '' then issAgainst = 0;
  if MGMTrec = 'Against' then do;
    if voteresult = 'Pass' then do; mgmt_win = 0; margin_mgmt = -abs(margin); end; else if voteresult = 'Fail' then do; mgmt_win = 1; margin_mgmt = abs(margin); end; end;
  if MGMTrec = 'For' then do;
    if voteresult = 'Pass' then do; mgmt_win = 1; margin_mgmt = abs(margin); end; else if voteresult = 'Fail' then do; mgmt_win = 0; margin_mgmt = -abs(margin); end; end;

proc sort data = drop.Proposal_list out = all_agenda nodupkey; by ISSAgendaItemID; 

proc sql;
  create table item_dates as
  select a.*, b.issue
  from item_dates as a, all_agenda as b
  where a.ISSAgendaItemID = b.ISSAgendaItemID; 
quit;

proc sort data = drop.Proposal_types; by ISSAgendaItemID agendaGeneralDesc itemDesc descending num_proposals;

data Proposal_types; set drop.Proposal_types; by ISSAgendaItemID agendaGeneralDesc itemDesc;
  if first.itemDesc; run;

proc sql;
  create table item_dates1 as
  select a.*, b.ISSAgendaItemID2
  from item_dates as a left join Proposal_types as b
  on a.ISSAgendaItemID = b.ISSAgendaItemID and a.agendaGeneralDesc = b.agendaGeneralDesc and a.itemDesc = b.itemDesc; 
quit;

proc sort data = item_dates1 (keep=companyid meetingID meetingDate cusip ticker recordDate issue issAgendaItemId agendaGeneralDesc itemDesc issAgendaItemId2 issFor issAgainst mgmt_win issue ISSAgendaItemID); 
  by companyid meetingID meetingDate cusip ticker recordDate;
  where issue ne '';

proc sql;
  create table past_recomm as
  select a.issAgendaItemId2, a.itemDesc, a.meetingdate, b.meetingID, b.issfor, b.issAgainst, b.mgmt_win, b.meetingdate as meetingdate2
  from proposals4b as a left join item_dates1 as b
  on a.issAgendaItemId2 = b.issAgendaItemId2 and 1 <= intck('month', b.meetingdate, a.meetingdate) <= 12;
quit; 

proc sort nodupkey; by issAgendaItemId2 meetingdate meetingID meetingdate2;
run;

proc means noprint; by issAgendaItemId2 meetingdate;
  var issFor issAgainst;
  output out = blanket2 (drop=_type_ _freq_) n = num_type2 mean = issFor2 issAgainst2;

data blanket2; set blanket2;
  if num_type2 > 1;
  if issagainst2 >= 0.95 or issfor2 >= .95 then blanket2 = 1;
run;
*** End of defining blanket recommendations by ISS;


proc sql;
  create table proposals5b as 
  select a.*, b.blanket2
  from proposals4b as a left join blanket2 as b
  on a.issAgendaItemId2 = b.issAgendaItemId2 and a.meetingdate = b.meetingdate;
quit;

proc sort data = proposals5b; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year;

data proposals5b; set proposals5b; by permno meetingdate mgmt_sponsored mgmt_win Itemdesc issAgendaItemId itemonagendaid mgmtFor issForMgmt issue margin year;
  if ind = . then ind = 48;
  if n_contested = . then n_contested = 0;
  ind_year = ind*10000+year;
  log_nanalyst = log(1+nanalyst);
  if 0 <= mgmt_win_nc < 1 then mgmt_lost_nc = 1; else mgmt_lost_nc = 0;

%winsor(dsetin=proposals5b, dsetout=proposals5b, byvar=none, vars=net_win_informed net_win_uninformed car126d_ff4 car126d_dgtw size mb leverage_b num_busseg capex sp500 roa mfo io io_hhi, type=winsor, pctl=1 99); 
run;

data proposals5b; set proposals5b;
  if 0 <= mgmt_win_nc < 1 then mgmt_lost_nc = 1; else mgmt_lost_nc = 0;
  if blanket = . then blanket = 0;
  if blanket2 = . then blanket2 = 0;

proc sort data=proposals5b out = temp.proposals_blanket nodupkey; by permno meetingdate itemonagendaid;
   where car63d_dgtw ~= . and iss_win ne . and mb ne . and leverage_b ne . and car63d_ff4 ne . and net_win_informed ne . and net_win_uninformed ne . and mgmt_win ne . and 
     iss_win ne . and size ne . and mb ne . and car_pr252d_m ne . and leverage_b ne . and capex ne . and sp500 ne . and mfo ne . and log_nanalyst ne .; *num_63d >= 21 and  and car63d_dgtw ~= . ;
run;

proc export data= temp.proposals_blanket
            outfile= "D:\Dropbox\InformedVoting\proposals_blanket.dta" 
            dbms=stata replace;
run;



